@synthesize name=_name的含义
2015-12-02 14:44
253 查看
@synthesize name=_name;
先看下下面的代码,经常在别人的源码中看到:
一直对@synthesize name=_name;这样的写法觉的很奇怪,这个_name是哪里来的?明明找不到它的定义,为什么编译器没报错?原来这个是系统生成的:
在64位系统中,系统会自动给类添加ivar(instance
variable),添加的ivar以一个下划线“_”做前缀,即类似_ivar这样的格式。
但在32位系统中,如果类的@interface部分没有进行ivar声明,但有@property声明,在类的@implementation部分有相应的@synthesize,则会得到类似下面的编译错误:
Synthesize property ‘xxx’ must either be named the same as a compatible ivar or must explicitly name an ivar。(可惜找不到32位系统验证这个问题)
所以最好写成像下面这样:
1、这样做的原因之一就是不暴露实例的成员变量。
在这里简单说一下_name和name的区别。_name是Person类的成员变量,name是属性。
属性是用self.name,通过getter方法来调用的,可以在类外使用。
而成员变量是通过_name来调用,只能在该类对应的implementation中使用,在类外不能使用。
在类内方法访问成员变量时就应该直接使用成员变量,即带下划线的名字_name,类内方法不推荐使用self.name,因为使用存取器本来就是对外的,在内部使用可能会造成一些不必要的错误,比如:
self.name= [[NSString alloc] init]; //retain count为2,处理不好易导致内存泄露。
2、这样的写法还能避免一些奇怪的问题
property和synthesize定义了一对getter和setter方法,在这里的getter方法是name,setter方法是setName,事实上getter和setter方法操作的是变量_name。
如果是@synthesize name=_name;其getter方法为:
如果是@synthesize name;其getter方法为:
当函数名和属性名重名的时候会出现未知的错误,为了避免这种情况,Apple的源码范例里面多数也采用@synthesize name=_name;这种方式。
在《Learn Objective-C on the Mac》中有这么一段话:
编译器和苹果公司都以下划线开头的形式保存实例变量名称,如果你尝试在其他地方使用下划线,可能出现严重的错误。这条规则不是强制性的,但是如果不遵守它,你可能会遇到某种风险.
转载地址:http://www.devdiv.com/ios_objective_c_property_instance_variable-blog-186016-51342.html
先看下下面的代码,经常在别人的源码中看到:
@interface Person : NSObject @property(nonamtic, retain) NSString *name; @end @implementatin Person @synthesize name=_name; @end
一直对@synthesize name=_name;这样的写法觉的很奇怪,这个_name是哪里来的?明明找不到它的定义,为什么编译器没报错?原来这个是系统生成的:
在64位系统中,系统会自动给类添加ivar(instance
variable),添加的ivar以一个下划线“_”做前缀,即类似_ivar这样的格式。
但在32位系统中,如果类的@interface部分没有进行ivar声明,但有@property声明,在类的@implementation部分有相应的@synthesize,则会得到类似下面的编译错误:
Synthesize property ‘xxx’ must either be named the same as a compatible ivar or must explicitly name an ivar。(可惜找不到32位系统验证这个问题)
所以最好写成像下面这样:
@interface Person : NSObject{ NSString *_name; } @property(nonamtic, retain) NSString *name; @end @implementatin Person @synthesize name=_name; -(void)dealloc{ [_name release]; [super dealloc]; } @end
1、这样做的原因之一就是不暴露实例的成员变量。
在这里简单说一下_name和name的区别。_name是Person类的成员变量,name是属性。
属性是用self.name,通过getter方法来调用的,可以在类外使用。
而成员变量是通过_name来调用,只能在该类对应的implementation中使用,在类外不能使用。
在类内方法访问成员变量时就应该直接使用成员变量,即带下划线的名字_name,类内方法不推荐使用self.name,因为使用存取器本来就是对外的,在内部使用可能会造成一些不必要的错误,比如:
self.name= [[NSString alloc] init]; //retain count为2,处理不好易导致内存泄露。
2、这样的写法还能避免一些奇怪的问题
property和synthesize定义了一对getter和setter方法,在这里的getter方法是name,setter方法是setName,事实上getter和setter方法操作的是变量_name。
如果是@synthesize name=_name;其getter方法为:
-(MyObject *)name { return _name; }
如果是@synthesize name;其getter方法为:
-(MyObject *)name { return name; }
当函数名和属性名重名的时候会出现未知的错误,为了避免这种情况,Apple的源码范例里面多数也采用@synthesize name=_name;这种方式。
在《Learn Objective-C on the Mac》中有这么一段话:
编译器和苹果公司都以下划线开头的形式保存实例变量名称,如果你尝试在其他地方使用下划线,可能出现严重的错误。这条规则不是强制性的,但是如果不遵守它,你可能会遇到某种风险.
转载地址:http://www.devdiv.com/ios_objective_c_property_instance_variable-blog-186016-51342.html
相关文章推荐
- STL remove和erase
- IDEA中的单工程多模块(基于maven)
- 《编程之美》——数组分割
- DEVICE_ATTR的使用
- pt-query-digest查询日志分析工具
- CSS的选择器
- 数论基础知识与定理
- ERROR 1201 (HY000):Could not initialize master info structure的问题(转载)
- 人类自然语言理解的一些技术分析
- hdu 油菜花王国
- hdu 油菜花王国
- C#递归搜索指定目录下的文件或目录
- Activiti学习笔记11 — 判断节点的使用
- Jprofiler监控工具(内存泄漏)
- 修改apache2的监听端口
- App图标适配
- “一致性哈希即Consistent Hashing” 和 “libconhash” 的学习感悟
- Linux-debian5,忘记root密码的解决办法
- linker command failed with exit code 1 (use -v to see
- LeetCode(260) Single Number III