欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

编写高质量代码

程序员文章站 2022-06-21 16:26:36
...

内存管理讲究的是"好借好还,在借不难

在现实生活中非常讲究"好借好还,再借不难"的规则,如果违法了这个规则哪就是"无赖"了.同样,这个规则在写程序代码的过程中非常有效.一点使用完了一个拥有的对象,应该使用releaseautorelease释放着个对象的所有权,而不要耍无赖;否则它将影响其他应用的正常运行.
通常,应该使用release而不是autorelease只有在不适合立即回收对象的情况下,才应该使用autorelease,如要从某个方法返回对象.

    注释:这并不是说`release`必然会引起对象的回收(只有当技术保留技术减少至0时才会发生回收),但它也有可能会发生.

如何防止出现"用完不马上归还"的情况?可以根据实际的情况,适当采取一些措施.当从一个方法中返回一个局部变量时,不仅要保证自己遵守了内存管理规则,而且要保证接收方子啊对象被释放之前一直有机会试用该对象.当返回一个新创建的(拥有的)对象时应该使用autorelease而不是�release来释放所有权.
请考虑一个很简单fullName方法,用它来连接fullNamelastName.一种可行的正确的现实方法(仅仅从内存管理的角度而言----当然,从功能的角度考虑,它仍有很多不足之处)可能如下面的代码所示:

- (NSSting *)fullName {
NSString*string = [NSSting stringWithFormat:@"%@,%@",firstName,lastName];
    return sting;
    }

按照组基本的规则,并不拥stringWithFormat返回的字符串,所以他可以安全地从该方法中返回.
下面这种方法实现也是正确的

- (NSString *)fullName {
NSString *sting = [[[NSString alloc]initWithFormat:@"%@,%@",firstName,lastName]autorelease];
return sting;
}

拥有alloc 返回的字符串,但随后向他发送了autorelease消息,因此在失去它的引用之前,已经放弃了所有权,并且这样做也符合内存管理的规则.这种实现的精髓在于使用了autorelease而不是�releas,要意识到这一点.
相比之下下面的代码就是错误的:(请勿模仿)

- (NSString *)fullName {
  NSString *sting = [[[NSString alloc]initWithFormat:@"%@,%@",firstName,lastName]release];

return sting;
}

纯粹从内存管理的角度来讲,他看起来是正确的:拥有alloc返回的字符串,并向它发送一条releasede 的信息来释放所用权.然而从实用家度来看,该字符串很有可能子啊某一步就被回收了(它可能没有任何其他的所有者),因此该方法的调用者会收到一个无效的对象,这说明了autorelease非常实用的原因 - 他能推迟释放,可以再未来的某一时刻过后再释放.
为了追去完整性所以下面的代码也是错误的:

- (NSString *)fullName {
NSString *sting = [[NSString alloc]initWithFormat:@"%@,%@",firstName,lastName];
return sting;
}

拥有alloc返回的字符串,再有机会施法所有权之前,就应该失去对象的引用.根据内存管理规则,这将导致内存泄漏,因为调用者没有得到任何迹象表明他们拥有返回的对象.

要点

(1)、在Objective - C中,释放对象应优先使用�release而非autorelease,但在不适合立即收回对象的情况下,应优先使用autorelease.
(2)、当返回一个创新的(拥有的)对象时,应该使用autorelease而不是release来释放所有权
(3)、对于拥有alloc返回的对象而言,失去释放所有权之前,应先失去对该对象的引用.