Iphone 在init中实例化NSDictionary/NSArray而无需额外保留的正确方法
我有许多类使用各种NSDictionary/NSArray集合类作为IVAR,但我经常遇到这样的问题:我的集合类在包含类发布之前就被发布了 这似乎主要发生在集合类上,而不是另一个模型类(即我单独创建的类或其他NS*非集合类) 以下是我和其他人做过的两种变化: @实现类XIphone 在init中实例化NSDictionary/NSArray而无需额外保留的正确方法,iphone,objective-c,memory-management,Iphone,Objective C,Memory Management,我有许多类使用各种NSDictionary/NSArray集合类作为IVAR,但我经常遇到这样的问题:我的集合类在包含类发布之前就被发布了 这似乎主要发生在集合类上,而不是另一个模型类(即我单独创建的类或其他NS*非集合类) 以下是我和其他人做过的两种变化: @实现类X // myDictionary declared as a property in the .h file as this: // @property (nonatomic, retain) NSMutableDictionar
// myDictionary declared as a property in the .h file as this:
// @property (nonatomic, retain) NSMutableDictionary *myDictionary;
@synthesize myDictionary;
- (id)int
{
if (self = [super init])
{
// Option 1:
// If I don't instantiate and assign with 'self',
// myDictionary ivar will not be available
// at times in doSomething.
myDictionary = [NSMutableDictionary dictionary];
// Option 2:
// Doing this, however will keep the dictionary around.
// because I have invoked an extra retain on the dictionary
self.myDictionary = [NSMutableDictionary dictionary];
// Which one is more correct?
}
return self;
}
- (void)doSomething
{
// this will give the error about trying to invoke
// a method on an already released instance
[myDictionary objectForKey:@"myKey"];
}
- (void)dealloc
{
// If I did self.myDictionary in 'init', I then
// need to do this:
[myDictionary release];
[super dealloc];
}
@end
那么,哪种方法是在类中保存NSDictionary实例的更正确的方法呢?选项2是正确的;选项1是错误的
但是您遗漏了最好的选项:
myDictionary=[[NSMutableDictionary alloc]init]
选项2是正确的;选项1是错误的
但是您遗漏了最好的选项:
myDictionary=[[NSMutableDictionary alloc]init]
我建议使用
myDictionary = [[NSMutableDictionary alloc] init];
如果调用[NSMutableDictionary],内存仅在您所在方法的范围内。一旦你离开这个方法,内存就会随之而去,这就是为什么如果你想保留这些值,你需要alloc/init
这就是为什么如果你没有遇到alloc,你不必释放
例如:
- (void) doSomething {
// Do not need to release this string
NSString *someText = @"Hello world!";
// You need to release this string:
NSString *otherText = [[NSString alloc] initWithString:@"Hello world!"];
[otherText release];
}
编辑:在@mipadi@st3fan之后删除了self,发现了我的错误。忘了把零钱寄出去了。谢谢你让我负责。我建议使用
myDictionary = [[NSMutableDictionary alloc] init];
如果调用[NSMutableDictionary],内存仅在您所在方法的范围内。一旦你离开这个方法,内存就会随之而去,这就是为什么如果你想保留这些值,你需要alloc/init
这就是为什么如果你没有遇到alloc,你不必释放
例如:
- (void) doSomething {
// Do not need to release this string
NSString *someText = @"Hello world!";
// You need to release this string:
NSString *otherText = [[NSString alloc] initWithString:@"Hello world!"];
[otherText release];
}
编辑:在@mipadi@st3fan之后删除了self,发现了我的错误。忘了把零钱寄出去了。谢谢你让我负责。为什么选项1错了?NSMutableDictionary类有一个静态初始值设定项方法,该方法返回一个空字典。@Justin,因为它是一个自动删除的字典,这意味着它将在运行循环的下一次旋转时消失,给ivar留下一个陈旧的指针。之后下次尝试访问它时,您将崩溃。
myDictionary=[[NSMutableDictionary]retain]代码>很好。苹果在他们的@Pumbaa80中很好地解释了这一点:我认为编写[[NSMutableDictionary]retain]
比使用我在回答中提到的标准alloc init版本没有任何好处。AFAIK唯一的区别是您的版本效率较低(它相当于[[[NSMutableDictionary alloc]init]autorelease]retain]
)。关于编程指南的推荐很好,我完全同意。我只是想解释版本1是如何被“修复”的,因为我认为贾斯汀对此感到困惑。为什么选项1是错误的?NSMutableDictionary类有一个静态初始值设定项方法,该方法返回一个空字典。@Justin,因为它是一个自动删除的字典,这意味着它将在运行循环的下一次旋转时消失,给ivar留下一个陈旧的指针。之后下次尝试访问它时,您将崩溃。myDictionary=[[NSMutableDictionary]retain]代码>很好。苹果在他们的@Pumbaa80中很好地解释了这一点:我认为编写[[NSMutableDictionary]retain]
比使用我在回答中提到的标准alloc init版本没有任何好处。AFAIK唯一的区别是您的版本效率较低(它相当于[[[NSMutableDictionary alloc]init]autorelease]retain]
)。关于编程指南的推荐很好,我完全同意。我只是想解释一下第1版是如何“修复”的,因为我认为Justin对此感到困惑。如果myDictionary
setter保留了它的参数,那么最终将导致内存泄漏。假设myDictionary
是一个保留属性(为什么它不会是)。。。这是错误的建议,会泄漏内存。@mipadi@st3fan你们都错了。他直接设置ivar,而不是使用setter方法。@戴夫·德隆:检查编辑历史记录,答案以前确实使用过setter。你对[NSDictionary dictionary]
如何管理内存的解释并不准确。您可以安全地从方法返回自动删除的词典。它至少会一直存在,直到它的自动释放池耗尽为止。如果myDictionary
setter保留了它的参数,那么最终将导致内存泄漏。假设myDictionary
是一个保留属性(为什么不是)。。。这是错误的建议,会泄漏内存。@mipadi@st3fan你们都错了。他直接设置ivar,而不是使用setter方法。@戴夫·德隆:检查编辑历史记录,答案以前确实使用过setter。你对[NSDictionary dictionary]
如何管理内存的解释并不准确。您可以安全地从方法返回自动删除的词典。它至少会一直存在,直到它的自动释放池被排干。