Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Chris Corbyn

macrumors newbie
Original poster
Jun 28, 2008
17
0
Melbourne, Australia
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
Code:
#import <Foundation/Foundation.h>
 
@protocol Talker
 
- (void) talk;
 
@end

Chatter.h
Code:
#import <Foundation/Foundation.h>
#import "Talker.h"
 
@interface Chatter : NSObject < Talker > {
  NSString *phrase;
}
 
- (void) setPhrase: (NSString *) phrase;
 
@end

Chatterbox.h
Code:
#import <Foundation/Foundation.h>
#import "Talker.h"
 
@interface Chatterbox : NSObject < Talker > {
  NSMutableArray *talkers;
}
 
- (void) addTalker: (id < Talker >) talker;
 
@end

Chatter.m
Code:
#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
Code:
#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
Code:
#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? :)
 

Chris Corbyn

macrumors newbie
Original poster
Jun 28, 2008
17
0
Melbourne, Australia
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

macrumors 6502
Mar 31, 2005
432
0
London, England
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.