I understand what basic synthesizing does in objective C but I don't understand what Apple is doing here. This shows up in the RootViewController of a project template with core-data and table views.
@synthesize managedObjectContext=__managedObjectContext;
What is the purpose of "__" and what are you doing when your are sysnthesising a object and setting equal to another object that is not used anywhere else in the view controller, although it is used in the app delegate?
I开发者_如何学Go also notice that __managedObjectContext is released in the dealloc method but not managedObjectContext.
The reason to do this is to protect the programmer from himself. Defensive programming. There are times when you want to access the value via the accessor (self.managedObjectContext
) and other times you want to efficiently access the instance variable directly (__managedObjectContext
).
This is a more general issue, and not specific to CoreData or managed object contexts. Without the = __managedObjectContext
portion, the instance variable and it accessor would have the same name. It's not an uncommon occurrence for someone to write managedObjectContext = foo;
which will forgo the accessor and the needed retain
. With the change of variable name you, your future self, and other readers of the code will more likely notice something problematic like __managedObjectContext = foo;
I will often shorten names inside the class as well with something like @synthesize managedObjectContext=_moc;
as a personal preference - keeping some of my code from wrapping due to long names. But the verbose and more readable interface is maintained.
It's not another object. That specifies the name of the instance variable that backs the property. For more information, see Declared Properties.
Suppose you have this piece of code:
@interface A {
Foo *_foo;
}
@property(nonatomic, retain) Foo *foo;
@end
@implementation A
@synthesize foo = _foo;
// ...
- (void)dealloc {
[_foo release];
[super dealloc];
}
@end
In this case the leading underscore ("_") is by convention, a way to differentiate between the name of the instance variable (iVar) and the name of the property. What this means is, you have a coding convention for differentiating between property access (via accessors) and direct access (via a pointer).
Also note, there is no value assignment whatsoever done in @synthesize foo = _foo;
. This simply indicates that the synthesized accessors should use the iVar named _foo
for storage.
Lastly, since _foo
is the name of your iVar, you have to write [_foo release]
. It is the iVar that's being released, not the property (see the distinction?).
I hope this helps...
Properties in Objective-C 2.0 are not objects but rather methods.
Back in Objective-C 1.0, you had to create your own accessors like so:
@interface RootViewController : UITableViewController {
NSManagedObjectContext *__managedObjectContext;
}
@end
@implementation RootViewController
-(NSManagedObjectContext *) managedObjectContext{
if (__managedObjectContext!=nil) {
return __managedObjectContext;
}
//... else initialize the context
[__managedObjectContext retain];
return __managedObjectContext;
}
-(void) setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext{
if (__managedObjectContext!=nil) {
[__managedObjectContext release];
__managedObjectContext=nil;
}
__managedObjectContext=managedObjectContext;
[__managedObjectContext retain];
}
You would use it like so:
NSManagedObjectContext *moc=[self managedObjectContext];
or
[self setManagedObjectContext:anotherContext];
As long as you always called the accessors you could be confident that the instance variable object would always be properly retained in released.
In Objective-C 2.0 the combined @property and @synthesize directives automate this entire property.
The property declaration is telling the pre-compiler what methods to create by name, readwrite, atomicity, retention etc.The synthesize directive tell the pre-compiler what property methods to autogenerate if they don't exist. By default it will also create an instance variable of the same name as a property. If you add the = someOtherSymbol
, it creates an instance variable of different name so that you won't accidentally refer to it.
The self-dot notation automatically calls the accessor method instead of directly accessing the instance variable. This is important because if you do this:
__managedObjectContext= aContext;
... the newly passed aContext
object is neither retained nor released and might either disappear unexpectedly or leak memory. That is because the direct reference does not call an accessor method whereas:
self.manageObjectContext= aContext;
or [self setManagedObjectContext:aContext];
both call accessor methods and automatically handle retention.
精彩评论