ios retain属性

众所周知IOS的retain属性来解决了一些指针引用问题,但同时如果不了解其特点,也就很容易导致double free或没有free.


Student *st;  //其中student为NSObject子类


@property (nonatomic,retain) Student *st; 


再来看一下点操作。

self.st = xxx;

其实是执行了setter操作,展开原形为:

- (void)setSt:(Student *) ast

{

//请注意以下不能使 用self.操作

[st release]; //st 为全局成员变量

st = nil;

        st = [ast retain];

}


如何清楚地认识自己的写法是否存在double free或存在泄漏.

习惯的几个写法:

-(void)viewDidLoad

{

[super viewDidLoad];


//写法一

        st = [[Student  alloc]init];   

        //写法二

        self.st = [[[Student  alloc]init]autorelease];  

        //写法三

        Student *tmpst = [[Student  alloc]init]; 

        self.st = tmpst;

        [tmpst release];

}


对应的dealloc写法

-(void) dealloc

{

        [st release]; //或 self.st = nil; 

[super dealloc];

}

分析:

对于方法一,没有使 用self.操作,即创建时retaincount = 1;

       但这种全局成员,在类中使用时,如果时常用来作为左值被赋值时,要非常小心,看前面是否已实例化过了,如果没有则可以直接赋值,如果有了,见议使用self.操作。

       举例(建立在上面例子的类中成员函数):

       - (void) functionA

{

        Student *otherst = [[Student alloc]init]; 

st = otherst;

        [otherst release];

}

如果是初始化即(viewDidLoad)中进行将st进行了实例化。哪么有再次执行functionA,就会有内存泄漏,为什么?虽然在functionA中otherst释放了。此时的st 也指向了一个野指针的地址,哪么哪一块内存没有释放呢,就是在viewDidLoad 中 alloc出来的哪块地址被丢失了。当执行方法A后,没有任何实例能找到哪块内存,因此释放不了。为了避免泄漏,可以将方法A中的st = otherst ;改为self.st = otherst;为什么这样一改就好了呢?来看一下self.st = otherst ;做了什么,展开实际上是执行[self setSt:otherst]:

- (void)setSt:(Student *) ast

{

[st release]; //在这里先把在viewDidLoad 中alloc的哪块内存释放了,

st = nil;  //并指向了NULL

        st = [ast retain];//再将新的内存地址引用计数+1 ,即此时这里的st 就指向了 otherst的内存了。

}

对方法一进行初始化的retain属性总结。只需要在初始化方法中进行alloc 一次,后续使用self.进行操作,可确保安全。

对于方法二的方法,我想看了方法一的分析应该很明白了,这种写法,其实是OC自动创建代码时的常用写法。简洁明了。整个类方法中除了自身set方法外,的其它地方都可以使 用self.来操作。

对于方法三,使用这种监时变量其实意义上是一样,只是看来麻烦,每次都搞个临时变量,增加代码上,不美观。


还有一个重点要注意的就是在内存告警的地方的写法:

- (void)didReceiveMemoryWarning

{

      [super didReceiveMemoryWarning];

      通常写法为

      self.st = nil;//这样安全吗?还是使用[st release];安全。

}

其实在这里安全是相对的.关键是清楚自己alloc出来的内存,什么时候release,过程中有没有release.


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

边缘998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值