objective-c – 关于@synthesize的问题
当您从嵌入CoreData的Xcode创建一个新的应用程序时,您将这些行放在委托的实现文件中:
@synthesize window=_window; @synthesize managedObjectContext=__managedObjectContext; 仅使用下划线或双重使用的区别是什么?仅写作有什么区别? @synthesize window; 解决方法
领先的下划线是一个有助于区分实例变量和访问器的命名约定.对于编译器,它只是一个常见的ivar重命名.
考虑差异(非ARC代码): self.date = [NSDate date]; // OK,the setter releases the old value first date = [NSDate date]; // WRONG,skipping the setter causes a memory leak _date = [NSDate date]; // WRONG but easier to see it's not a local variable 使用ARC变量不会泄漏,但是跳过@property属性仍然是错误的: @property (copy) string; // ... self.string = someString; // OK,string is copied string = someString; // WRONG string is retained but not copied _string = someString; // WRONG but hopefully easier to see 最糟糕的是,一些API,如Core Data依赖KVC通知来执行延迟加载.如果您不小心跳过访问者,您的数据将恢复为零. 这是你经常发现@synthesize var = _var的原因,这使得 > self.var一个访问器引用(调用setter和getter), 鉴于@synthesize var = _var在省略@synthesize时由LLVM 4.0自动生成,您可以将其视为Objective-C中的默认命名约定. 继续阅读详细信息… 现代运行时 在Objective-C 2.0中,你声明了这样的变量: @interface User : NSObject @property (nonatomic,assign) NSInteger age; @end @implementation User { @synthesize age; // this line can be omitted since LLVM 4.0 @end 由编译器翻译如下: @interface User : NSObject { NSInteger age; } @end @implementation User -(void)setAge:(NSInteger)newAge { age=newAge; } -(void)age { return age; } @end 如果您喜欢使用下划线约定,只需添加以下内容: @synthesize age=_age; 这就是你所需要的,因为with the modern runtime,如果你不提供一个实例变量,编译器为你添加一个.这是编译的代码: @interface User : NSObject { NSInteger _age; } @end @implementation User -(void)setAge:(NSInteger)newAge { _age=newAge; } -(void)age { return _age; } @end 如果添加ivar和@property,会发生什么?如果变量具有相同的名称和类型,编译器会使用它来生成一个新的变量.引用Objective-C编程语言>声明属性> Property Implementation Directives:
传统运行时 但是,如果您需要support the legacy runtime,则必须提供具有相同名称和兼容类型的实例变量,或者在@synthesize语句中指定另一个现有实例变量. 所以没有下划线的遗留代码将是: @interface User : NSObject { NSInteger age; } @property (nonatomic,assign) NSInteger age; @end @implementation User @synthesize age; @end 或者如果您喜欢下划线约定: @interface User : NSObject { NSInteger _age; } @property (nonatomic,assign) NSInteger age; @end @implementation User @synthesize age = _age; @end 什么是最好的方法? 苹果不鼓励在方法中使用下划线,而不是使用变量! 苹果方法:Coding Guidelines for Cocoa: Typographic Conventions:
苹果对变量:Declared Properties and Instance Variables
ISO/IEC 9899 7.1.3 Reserved identifiers(又名C99):
除此之外,双引导下划线传统上保留给预处理器/编译器/库的供应商.这避免了您在代码中使用__block的情况,而Apple则将其作为新的非标准关键字引入. Google Objective-C Style guide:
在Xcode触发自动完成功能之前,Google尾随的下划线不会强制您再输入一个字符,但如果下划线是后缀,您会发现它是一个实例变量. C(参见What are the rules about using an underscore in a C++ identifier?)和Core Data属性(尝试在模型中添加领先的下划线)也不鼓励领先的下划线,您将获得“名称必须以字母开头”). 无论你选择什么,碰撞都不太可能发生,如果这样做,你会得到编译器的警告.当有疑问时,使用默认的LLVM方式:@synthesize var = _var; 我拥有这篇文章的编辑,由Mark Dalrymple阅读A Motivation for ivar decorations.你可能想检查一下. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |