您的位置:首页 > 其它

@synthesize name=_name的含义

2015-12-02 14:44 253 查看
@synthesize name=_name;

先看下下面的代码,经常在别人的源码中看到:

@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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: