Apple模板iOS文件,包含核心数据和表视图

时间:2011-07-04 17:07:44

标签: objective-c ios core-data

我理解目标C中的基本合成是什么,但我不明白Apple在这里做了什么。这显示在具有核心数据和表视图的项目模板的RootViewController中。

@synthesize managedObjectContext=__managedObjectContext;

“__”的目的是什么?当你对一个对象进行sysnthes化并设置等于另一个在视图控制器中没有使用过的对象时,你在做什么,虽然它在app delegate中使用?

我还注意到__managedObjectContext是在dealloc方法中发布的,而不是在managedObjectContext中发布的。

4 个答案:

答案 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];

调用访问器方法并自动处理保留。