@synthesize name=_name的含义

转载地址:http://www.devdiv.com/ios_objective_c_property_instance_variable-blog-186016-51342.html

@synthesize name=_name;


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

@interface Person : NSObject

@property(nonamtic, retain) NSString *name;

@end

@implementatin Person

@synthesize name=_name;    

@end

一直对@synthesize name=_name;这样的写法觉的很奇怪,这个_name是哪里来的?明明找不到它的定义,为什么编译器没报错?原来这个是系统生成的:

64位系统中,系统会自动给类添加ivarinstance 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、这样做的原因之一就是不暴露实例的成员变量。

在这里简单说一下_namename的区别。_namePerson类的成员变量,name是属性。

属性是用self.name,通过getter方法来调用的,可以在类外使用。

而成员变量是通过_name来调用,只能在该类对应的implementation中使用,在类外不能使用。

在类内方法访问成员变量时就应该直接使用成员变量,即带下划线的名字_name,类内方法不推荐使用self.name,因为使用存取器本来就是对外的,在内部使用可能会造成一些不必要的错误,比如:

self.name= [[NSString alloc] init];     //retain count为2,处理不好易导致内存泄露。

2、这样的写法还能避免一些奇怪的问题

propertysynthesize定义了一对gettersetter方法,在这里的getter方法是namesetter方法是setName,事实上gettersetter方法操作的是变量_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》中有这么一段话:

编译器和苹果公司都以下划线开头的形式保存实例变量名称,如果你尝试在其他地方使用下划线,可能出现严重的错误。这条规则不是强制性的,但是如果不遵守它,你可能会遇到某种风

险。

你可能感兴趣的:(@synthesize name=_name的含义)