区别如下:
1. 通过self.xxx 访问的方法的引用,包含了set和get方法。而通过ios 属性下划线是获取自己的实例变量,不包含set和get的方法。
2. self.x xx是对属性的访问;而ios 属性_xxx是对局部变量的访问,所有被声明为属性的成员。再ios5之前需要使用编译指令@synthesize 来告诉编译器帮助生成属性的getter和setter方法,之后这个指令可以不用认为的指定了,默认情况下编译器会帮助生成。编译器在生成getter,setter方法时是有优先级的,它首先查找当前的类中用户是否定义属性的getter,setter方法,如果有,则编译器会跳过,不会再生成,使用用户定义的方法。也就是说在使用self.xxx时是调用一个getter方法。会使引用计数加一,而ios 属性_xxx不会使用引用技术加一的。
3. 所有使用self.xxx是更好的选择,因为这样可以兼容懒加载,同时也避免了使用下滑线的时候忽略了self这个指针,后者容易在BLock中造成循环引用。同时,使用ios 属性 _是获取不到父类的属性,因为它只是对局部变量的访问。
因此,self方法实际上是用了get和set方法间接调用,ios 属性下划线方法是直接对变量操作。
使用self.的方法赋值的retaincount是对的。
@property 关键字的作用是 给实例变量在.h文件里创建一个set/get函数的申明。
等同于 你自己在.h文件里面给实例变量写set/get函数申明。
@property (nonatomic,retain) UIView *view2;
等于
-(UIView*)getView2;
-(void)setView2:(UIView*)view;
在.m文件里的@synthesize关键字就是自动实现set/get函数。
retain关键字的作用是,在实现set函数内部,retain当前变量,具体实现是这样:
-(void)setView2:(UIView*)view
{
[_view2 release];
_view2 = [view retain];
}
而
self.view2 = tView;
等于
[self setView2:tview];
也就是说,如果不用self.调用实例变量,retain关键字是不起作用的。
self.view2 = tView; 之后 其实tView和view2都是同一个对象,只是这个赋值的发操作把tView的retaincount+1了而已。所以当 [tView release]之后,self.view2的retaincount-1。然后当再次给 self.view2赋值的时候,在set内部会再次release。这样是不会有内存泄露的。
--------------------------------------------------------------------------------------------------------------
在不使用self.的图片里,为什么在 [tView release]之后,retaincount还是1呢?
这是因为 [tView release]之后, tView retaincount实际变成了0,然后tView 就被释放掉了。
你后面调用tView.retainCount其实是没意义的,tView已经被释放了。
所以你看到的1其实是,retainCount,retainCount2这2个变量前面被赋值的值。
你如果改成赋值给一个新的变量,你就会发现是0了。而这个0其实是新的变量的初始化的值0,并不是tView.retainCount返回的0。