我理解目标C中的基本合成是什么,但我不明白Apple在这里做了什么。这显示在具有核心数据和表视图的项目模板的RootViewController中。
@synthesize managedObjectContext=__managedObjectContext;
“__”的目的是什么?当你对一个对象进行sysnthes化并设置等于另一个在视图控制器中没有使用过的对象时,你在做什么,虽然它在app delegate中使用?
我还注意到__managedObjectContext是在dealloc方法中发布的,而不是在managedObjectContext中发布的。
答案 0 :(得分:0)
这不是另一个对象。它指定支持该属性的实例变量的名称。有关详细信息,请参阅Declared Properties。
答案 1 :(得分:0)
原因这样做是为了保护程序员免受他自己的伤害。防守编程。有时您希望通过访问者(self.managedObjectContext
)访问该值,有时您希望直接有效地访问实例变量(__managedObjectContext
)。
这是一个更普遍的问题,并非特定于CoreData或托管对象上下文。如果没有= __managedObjectContext
部分,实例变量和访问器将具有相同的名称。有人写managedObjectContext = foo;
来放弃访问者和所需的retain
并不罕见。随着变量名称的更改,您,未来的自我以及代码的其他读者将更有可能发现有问题的问题,如__managedObjectContext = foo;
我经常会缩短班级内的名字,以及@synthesize managedObjectContext=_moc;
作为个人偏好的东西 - 由于长名称而使我的一些代码不被包装。但是维护了冗长且易读的界面。
答案 2 :(得分:0)
假设你有这段代码:
@interface A {
Foo *_foo;
}
@property(nonatomic, retain) Foo *foo;
@end
@implementation A
@synthesize foo = _foo;
// ...
- (void)dealloc {
[_foo release];
[super dealloc];
}
@end
在这种情况下,前导下划线(“_”)是约定,这是一种区分实例变量名称(iVar)和属性名称的方法。这意味着,您有一个编码约定,用于区分属性访问(通过访问器)和直接访问(通过指针)。
另请注意,@synthesize foo = _foo;
中没有任何值分配。这只是表明合成访问器应该使用名为_foo
的iVar进行存储。
最后,由于_foo
是您的iVar的名称,因此您必须编写[_foo release]
。是iVar被释放了,而不是属性(参见区别?)。
我希望这会有所帮助......
答案 3 :(得分:0)
Objective-C 2.0中的属性不是对象,而是方法。
回到Objective-C 1.0,您必须创建自己的访问器,如下所示:
@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];
}
你会像这样使用它:
NSManagedObjectContext *moc=[self managedObjectContext];
或
[self setManagedObjectContext:anotherContext];
只要您始终调用访问者,您就可以确信实例变量对象始终在发布时正确保留。
在Objective-C 2.0中,组合的@property和@synthesize指令使整个属性自动化。
属性声明告诉预编译器通过名称,读写,原子性,保留等创建哪些方法.synthesis指令告诉预编译器,如果它们不存在,则自动生成哪些属性方法。默认情况下,它还将创建与属性同名的实例变量。如果添加= someOtherSymbol
,它会创建一个不同名称的实例变量,以便您不会意外地引用它。
自点符号自动调用访问器方法,而不是直接访问实例变量。这很重要,因为如果你这样做:
__managedObjectContext= aContext;
...新传递的aContext
对象既未保留也未释放,可能会意外消失或内存泄漏。这是因为直接引用不会调用访问器方法,而是:
self.manageObjectContext= aContext;
或 [self setManagedObjectContext:aContext];
调用访问器方法并自动处理保留。