Objective c 关于@synthesis的问题
从嵌入CoreData的Xcode创建新应用程序时,代理的实现文件中有以下行:Objective c 关于@synthesis的问题,objective-c,xcode,Objective C,Xcode,从嵌入CoreData的Xcode创建新应用程序时,代理的实现文件中有以下行: @synthesize window=_window; @synthesize managedObjectContext=__managedObjectContext; 只使用下划线或将下划线加倍有什么区别?只写有什么区别: @synthesize window; 你可以用 @合成窗口 但是,如果您的实例变量名为“window”,则有些人会使用一种命名约定,即在所有实例变量前加下划线,但仍然希望其getter和
@synthesize window=_window;
@synthesize managedObjectContext=__managedObjectContext;
只使用下划线或将下划线加倍有什么区别?只写有什么区别:
@synthesize window;
你可以用
@合成窗口
但是,如果您的实例变量名为“window”,则有些人会使用一种命名约定,即在所有实例变量前加下划线,但仍然希望其getter和setter不加下划线前缀,这就是“window=\u window”的意思
我不知道双下划线是什么意思,但我怀疑这也是命名约定的问题。前导下划线是一种命名约定,有助于区分实例变量和访问器。对于编译器来说,这只是一个常见的ivar重命名 考虑差异(非ARC代码): 使用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(如核心数据)依赖KVC通知来执行延迟加载。如果您不小心跳过了访问器,您的数据将返回为零
这就是为什么您经常会发现@synthesis var=\u var
,这使得
访问器引用(调用setter和getter)self.var
直接访问引用(跳过setter和getter)\u var
- 和
无效引用李>var
现代运行时 在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;
这就是您所需要的,因为如果您不提供实例变量,编译器会为您添加一个实例变量。下面是编译的代码:
@interface User : NSObject {
NSInteger _age;
}
@end
@implementation User
-(void)setAge:(NSInteger)newAge {
_age=newAge;
}
-(void)age {
return _age;
}
@end
如果同时添加ivar和@property,会发生什么?如果变量具有相同的名称和类型,编译器将使用它来生成新变量。引用Objective-C编程语言>声明的属性>:
访问器合成的行为存在差异
取决于运行时:
- 对于现代运行时,根据需要合成实例变量。如果已存在同名的实例变量,则为 用过
- 对于遗留运行时,实例变量必须已经在当前类的@interface块中声明。如果一个实例 存在与属性同名的变量,如果其类型为 如果与属性的类型兼容,则使用它-否则,您将获得 编译器错误
@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
最好的方法是什么?
Apple不鼓励在方法中使用下划线,但不鼓励在变量中使用下划线
苹果公司的方法:
避免使用下划线
字符作为前缀,表示私有,
尤其是在方法上。苹果储备
本公约的使用。使用
第三方可能导致
名称空间冲突;他们可能
无意中覆盖现有的
用他们自己的方法,
造成灾难性后果
关于变量的苹果:
确保实例变量的名称简洁地描述了
属性存储。通常,您不应该访问实例变量
相反,您应该直接使用访问器方法(您不需要访问
直接在init和dealloc方法中使用实例变量)帮助
发出此信号,在实例变量名称前加下划线(41;,
例如:@implementation MyClass{BOOL\u showsTitle;}
(又名C99):
- 以下划线和大写字母开头的所有标识符 字母或其他下划线是 总是为任何用途保留李>
- 全部 以 下划线始终保留供使用 作为标识符,在两者中都具有文件作用域 普通和标记名称空间
\uu block
的情况,苹果将其作为一个新的非标准关键字引入
:
变量名变量名开始
使用小写字母,并使用大小写混合
划出单词。类成员变量
有尾随的下划线。对于
示例:myLocalVariable,
myInstanceVariable\uU4。成员用于
KVO/KVC绑定可以从
使用
Objective-C2.0的@property不是
允许
Google的尾随下划线不会强制您在Xcode触发自动完成之前再键入一个字符,但您会意识到,如果下划线是后缀,则它是一个实例变量
< P>下划线也被禁止在C++(参见)和核心数据属性(尝试添加一个领先的下划线在模型中,你会得到“名称必须以字母开头”)。
无论您选择什么,冲突都不太可能发生,如果发生冲突,编译器会发出警告。如有疑问,请使用默认的LLVM方式:@synthesis var=\u var代码>
我拥有马克·达尔林普的这篇文章的编辑。您可能想查看它。这已被要求死亡。为了帮助搜索现有的问题,\uu
被称为und
@interface User : NSObject {
NSInteger _age;
}
@property (nonatomic, assign) NSInteger age;
@end
@implementation User
@synthesize age = _age;
@end