有没有人知道为什么XCode模板(至少在XCode 4.3.2中)有一些带有两个下划线的ivars和一些只带有一个下划线的ivars?
例如,Master-Detail应用程序模板包含文件MasterViewController.m,其中可以找到:
@synthesize detailViewController = _detailViewController;
@synthesize fetchedResultsController = __fetchedResultsController;
@synthesize managedObjectContext = __managedObjectContext;
感谢。
答案 0 :(得分:5)
这是一小群蠕虫。
下划线用于@synthesize,主要用于区分实例变量和访问者名称。这很重要,特别是如果您不仅仅是访问访问器中的变量(例如,延迟初始化)。如果它们是同一个名字,你可以轻松输入“foo”并获取实例变量,当你的意思是“self.foo”调用accessor方法时。所以,这就是为什么在这种情况下使用下划线的原因。
现在,Apple已经表示我们不应该在私有方法名称中使用前导下划线。它们使用该约定作为其私有方法名称,并且您可能无意中覆盖其中一个基类方法。那会很糟糕,特别是因为你无法在编译时捕获它。
但是,他们已经说过对私有实例变量使用下划线是可以的。事实上,作为一个例子,他们说在合成属性时使用ivars的前导下划线是完全可以的(并建议)。
现在,抓住了。它们还为私有实例变量使用单个前导下划线。所以,如果你有相同的名字,你可能会有冲突。为了看到这一点,在视图控制器方法的实现中,他们'_'并查看代码完成的方式。
那么,他们为什么不劝阻这种命名行为呢?因为冲突是在编译时捕获的。您不能拥有两个具有相同名称的实例变量。如果您尝试这样做,则会收到错误。
现在,为什么他们的代码模板会生成带有双下划线的名称?我不知道。 “实现”实际上保留了前导双下划线(后跟大写字母),但我们看到像__block这样的ObjC添加。
对于我的钱,我避免使用领先的双下划线。 Apple可以在生成的代码中做任何他们想做的事情。 FWIW,他们为ARC生成的一些代码仍然引用旧的非ARC关键字,所以我不会将他们生成的代码作为福音。 FWIW,我当然会不保留他们为Core Data生成的代码。至少,您应该更改(在managedObjectContext访问器方法中):
__managedObjectContext = [[NSManagedObjectContext alloc] init];
到
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
顺便说一句,我看到人们使用美元符号作为其私人合成名称的前导或尾随字符。
@synthesize foo = $foo;
@synthesize bar = bar$;
我已经写了超过25年的C / C ++,但我对ObjC来说还是比较新的,它有自己的复杂性。所以,我不是语言律师。我甚至都不是律师助理。我所知道的是它似乎是合法的 - 它适用于我尝试过的所有东西,尽管我不能肯定地说美元符号不应该被用于别的东西。 Xcode语法高亮显示器不喜欢它(它不会使用变量名的其余部分对其进行着色)。
我希望这足以让你回答你的问题,虽然这可能只会刺激你更多的问题......