在没有额外保留的情况下在init中实例化NSDictionary / NSArray的正确方法

时间:2010-09-02 18:22:53

标签: iphone objective-c memory-management

我有很多类使用各种NSDictionary / NSArray集合类作为ivars但是我经常遇到我的集合类在发布包含类之前被释放的问题。

这似乎主要发生在集合类而不是另一个模型类(即我单独创建的类或其他NS *非集合类)。

以下是我做过的两个变化,其他人看到过:     @implementation ClassX

// 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 个答案:

答案 0 :(得分:2)

选项2是正确的;选项1是错误的。

但是你遗漏了最好的选择:myDictionary = [[NSMutableDictionary alloc] init]

答案 1 :(得分:1)

我建议使用

myDictionary = [[NSMutableDictionary alloc] init];

如果调用[NSMutableDictionary dictionary],内存仅在您所使用的方法范围内。离开方法后,该内存与它一起使用,这就是为什么要保留值时需要alloc / init的原因。

这就是为什么如果你没有遇到分配就不必发布。

例如:

- (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之后删除了自己并抓住了我的错误。忘了张贴变更。谢谢你让我负责。