views:

96

answers:

2

I've been going through the screencasts here to learn how to write a table-based iPhone application, and it's been going pretty smoothly so far. Presently I'm halfway through the third episode, and it's starting to hit a snag.

In order to remove temporary hard-coding for the top layer of the table, the tutorial creates an NSMutableDicitonary for all the entries and their data, and then creates an NSArray using the forKeys statement to get an array with just the headwords to display in the table cells.

The problem I'm having is that the variable for the array refuses to synthesize.

The offending variable is defined in the AppDelegate.h file with the rest of the properties as follows:

@property (readonly) NSArray *recipes;

It is then synthesized and implemented in the AppDelegate.m file as follows:

@synthesize recipes;

- (NSArray *)recipes {
    return [data allKeys];
}

I inquired with the author of the screencast, and he suggested the following for AppDelegate.h:

@class Foo :NSObject {
    NSArray *_recipes;
}

@property(nonatomic, retain)NSArray *recipes;

@end

And this for AppDelegate.m:

@implementation Foo

@synthesize recipes = _recipes;

@end

I tried this method, but it created more errors than there were before. What makes this variable definition different from any other @property, and how can I make it behave?

+2  A: 

@synthesize generates a simple method to access the property. Since your accessor method is more complex, it can't be generated with @synthesize.

- (NSArray *)recipes {
    return [data allKeys];
}
Will Harris
Went off without a hitch or any further modification just changing that one word. Thanks a lot!
Kaji
@dynamic is not needed *unless* you are going to dynamically provide the implementation.
bbum
Thanks, bbum. I've been using @dynamic all this time even when it wasn't needed.
Will Harris
+9  A: 

@property is "merely" a shorthand for method declarations. @dynamic means that you'll dynamically provide the implementations at runtime, an advanced use pattern that is atypical.

Thus:

@property (readonly) NSArray *recipes;

Is, in the header, shorthand for:

- (NSArray *) recipes;

@synthesize recipes; will synthesize the methods implied by the @property declaration. No more, no less. Since someone mentioned it, @synthesize recipes=_recipes; will synthesize the methods, but use the instance variable _recipes for storage (and not recipes).

If you implement your own getter (since this is readonly, there is only a getter), of the form:

- (NSArray *) recipes {
    return ....;
}

Then there is no need for either @synthesize or @dynamic.

bbum
+1 for a _far_ better answer.
Abizern