当前位置:  开发笔记 > IOS > 正文

stringWithString中的对象所有权和NSString中的initWithString

如何解决《stringWithString中的对象所有权和NSString中的initWithString》经验,为你挑选了2个好方法。

我知道任何init ...方法都会初始化一个新对象,并且NSString stringWithString会将参数字符串的副本作为新对象.我也理解作为对象的所有者,我可以控制我分配的任何对象的释放/释放.我不明白的是什么时候我会使用stringWithString方法,因为任何以这种方式分配的局部变量都会让它的内存由NSString而不是本地类"拥有".

Kochan的"Objective in Objective C"一书(第1版)使用以下代码(参见第342-344页)来解释initWithString比stringWithString更可取,因为AddressCard类将拥有名称变量contents.另外,使用stringWithString方法重复调用setName版本时,我没有任何错误.TIA!

//header file has appropriate declarations but not included here:
#import "AddressCard.h"

@implementation AddressCard;

-(NSString *) name
{
   return name;
}

//Recommended code:
-(void) setName: (NSString *) theName
{
   [name release]
   name = [[NSString alloc] initWthString: theName];
}

//Incorrect code according to Kochan:
-(void) setName: (NSString *) theName
{
   [name release]
   name = [NSString stringWthString: theName];
}

//rest of class implementation code snipped
@end

Peter Hosey.. 27

我不明白的是什么时候我会使用stringWithString方法,因为任何以这种方式分配的局部变量都会让它的内存由NSString而不是本地类"拥有".

什么?没有.

规则很简单:

任何对象返回的alloc,copy,copyWithZone,或new具有为1的保留计数.

retain 增加接收对象的保留计数.

release 减少接收对象的保留计数.

autorelease告诉当前自动释放池向接收对象发送release消息"稍后".

名称中没有"new"或"copy"的任何工厂方法(例如stringWithString:)返回一个代表您自动释放的对象.

或者,消化了一下:

任何方法的名称包含copy,alloc,retain,或new返回你自己的对象.

任何没有的方法都会返回一个你不拥有的对象.

拥有一个对象,保留它.

setName:您显示的错误实现是不正确的,因为它将一个自动释放的对象存储在实例变量中,当您意味着拥有该对象时.你应该保留它,或者在这种情况下,复制它.一种方法是简单地使用,alloc并且initWithString:如您所示的正确示例; 另一种方式copy.

Cocoa的内存管理编程指南解释了一切.每个Cocoa或Cocoa Touch程序员都应该不时阅读或重新阅读.



1> Peter Hosey..:

我不明白的是什么时候我会使用stringWithString方法,因为任何以这种方式分配的局部变量都会让它的内存由NSString而不是本地类"拥有".

什么?没有.

规则很简单:

任何对象返回的alloc,copy,copyWithZone,或new具有为1的保留计数.

retain 增加接收对象的保留计数.

release 减少接收对象的保留计数.

autorelease告诉当前自动释放池向接收对象发送release消息"稍后".

名称中没有"new"或"copy"的任何工厂方法(例如stringWithString:)返回一个代表您自动释放的对象.

或者,消化了一下:

任何方法的名称包含copy,alloc,retain,或new返回你自己的对象.

任何没有的方法都会返回一个你不拥有的对象.

拥有一个对象,保留它.

setName:您显示的错误实现是不正确的,因为它将一个自动释放的对象存储在实例变量中,当您意味着拥有该对象时.你应该保留它,或者在这种情况下,复制它.一种方法是简单地使用,alloc并且initWithString:如您所示的正确示例; 另一种方式copy.

Cocoa的内存管理编程指南解释了一切.每个Cocoa或Cocoa Touch程序员都应该不时阅读或重新阅读.



2> Boaz Stuller..:

实际上,两个人都错了.由于一般的内存管理原因(其他地方已经很好地阐述),"错误的"错误."推荐"的错误有两个原因:

    if(theName == name),那么你可能会在第一行释放你的对象,然后尝试在第二行使用deallocated对象作为-initWithString:的参数,导致未定义的行为.

    -initWithString:不处理优雅地传递nil.

'正确'(恕我直言)方法是:

-(void) setName: (NSString *) theName
{
   if (theName == name) return; // if they're equal, no need to do anything further
   [name release];
   name = [theName copy];  // sets name to nil if theName is nil
}

对于大多数对象,你实际上想要在第三行上获得而不是-copy,但对于字符串来说,复制几乎总是更好.

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有