PDA

View Full Version : I can't get fast-enumeration to work?




Chris Corbyn
Jun 28, 2008, 06:55 AM
I'm not sure what I'm doing wrong here. My understanding is that my "Chatterbox" class should iterate over all "Chatter" instances it has in its internal array. However, although the compiler (gcc on OS X) doesn't generate any errors or warnings, no iterations occur in the loop. I've even added some straight printf() calls to the loop to double-check.

Talker.h
#import <Foundation/Foundation.h>

@protocol Talker

- (void) talk;

@end


Chatter.h
#import <Foundation/Foundation.h>
#import "Talker.h"

@interface Chatter : NSObject < Talker > {
NSString *phrase;
}

- (void) setPhrase: (NSString *) phrase;

@end


Chatterbox.h
#import <Foundation/Foundation.h>
#import "Talker.h"

@interface Chatterbox : NSObject < Talker > {
NSMutableArray *talkers;
}

- (void) addTalker: (id < Talker >) talker;

@end


Chatter.m
#import <Foundation/Foundation.h>
#import "Chatter.h"

@implementation Chatter

- (void) setPhrase: (NSString *) newPhrase {
phrase = newPhrase;
}

- (void) talk {
printf("%s\n", [phrase cStringUsingEncoding: NSUTF8StringEncoding]);
}

@end


Chatterbox.m
#import <Foundation/Foundation.h>
#import "Chatterbox.h"
#import "Talker.h"

@implementation Chatterbox

- (void) addTalker: (id < Talker >) talker {
[talkers addObject: talker];
}

- (void) talk {
//Something doesn't work here... it's not iterating
for (id < Talker > *talker in talkers) {
[talker talk];
}
}

@end


main.m
#import <Foundation/Foundation.h>
#import "Chatter.h";
#import "Chatterbox.h"

int main(Void) {

NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];

Chatterbox *chatterbox = [[Chatterbox alloc] init];

Chatter *c1 = [[Chatter alloc] init];
[c1 setPhrase: @"Hello Melbourne!"];
[chatterbox addTalker: c1];

Chatter *c2 = [[Chatter alloc] init];
[c2 setPhrase: @"Hello Australia!"];
[chatterbox addTalker: c2];

Chatter *c3 = [[Chatter alloc] init];
[c3 setPhrase: @"Hello World!"];
[chatterbox addTalker: c3];

Chatter *c4 = [[Chatter alloc] init];
[c4 setPhrase: @"Hello Universe!"];
[chatterbox addTalker: c4];

[chatterbox talk];

[c1 release];
[c2 release];
[c3 release];
[c4 release];

[autoreleasepool release];

}


Any ObjC developers here who can tell me what I'm doing wrong? :)



Nutter
Jun 28, 2008, 08:07 AM
You need to override -init in the Chatterbox class in order to assign an instance of NSMutableArray to the talkers instance variable.

Chris Corbyn
Jun 28, 2008, 08:44 AM
OMG, I can't believe I missed that, and I can't believe it just runs compiles without even a warning :-S Is that something to do with unitialized objects being "nil" by default? Sorry if that's a really elementary question, I've only been looking at this language for a day.

You need to override -init in the Chatterbox class in order to assign an instance of NSMutableArray to the talkers instance variable.

Nutter
Jun 28, 2008, 10:23 AM
Yes, instance variables always start out set to nil. Sending messages to nil always fails silently in Objective-C. This may take some getting used to, and it can catch you out at times, but it can help you to write very elegant code.

Chris Corbyn
Jun 28, 2008, 06:25 PM
Thank you :)