2011-12-26 95 views
0

我对自定义初始化方法自动释放对象的原理有些困惑。例如:在自定义初始化方法中自动释放

- (id)initWithId: (unsigned long)personID { 
    self = [super init]; 
    if (self) { 
     self.ID = personID; 
    } 

    return self; 
} 

根据objc编码约定,我必须在返回时自动释放自我。但是那种代码不断破碎。我错过了什么吗?我应该自动释放这些方法手动创建的对象,但不是“自己”,像这样?

- (id)makeWithId: (unsigned long)personID { 
    Person *obj = [[Person init] alloc]; 

    if (obj) { 
     obj.ID = personID; 
    } 

    return [obj autorelease]; 
} 

在此先感谢。

+1

你是否坚持在调用代码中返回的对象? – Abizern 2011-12-26 16:55:24

+0

这没关系=)这都是关于autorelease的原理。我的意思是:如果我调用'SomeClass sc = [SomeClass alloc] init];'我在使用它后肯定会释放sc。但如果我调用'SomeClass sc = [[SomeClass alloc] initWithSomeParam:123]'我不需要释放它,我不负责它(initWithSomeParam是)。 – Stormherz 2011-12-26 17:06:47

+4

@Stormherz,你错了。如果你调用了'alloc',你有责任释放它。如果你已经调用过'[SomeClass someClassWithSomeParam:5]',那么你不需要负责它,它是自动释放的。 – joerick 2011-12-26 17:11:12

回答

3

在Cocoa中,有这样的约定:

  • 方法与alloc启动或new返回与保持数+1
  • 是创建一个对象返回一个自动释放对象的所有其他方法的对象。

请注意,使用上面发布的init方法,不会创建对象。以前的alloc调用会创建该对象。这只是设置并准备好使用。

至于你的makeWithId方法,你已经混淆了两个概念。像这样的工厂方法应该是类方法(即用+声明,而不是-)。这时你会使用它像

Person *p = [Person makeWithId:3]; 

既然这样,你比方法调用的返回接收器不同的对象。这意味着,当你做

Person *p = [[Person alloc] makeWithId:3]; 

alloc创建Person对象已被泄露,并p会被自动释放。

因此,总结一下,从类“工厂”方法返回自动释放对象,并且不要在init方法中执行任何内存管理。

+0

arghhh,我没有在这里分配任何东西,我的空头,我肯定这次是过度劳累=)非常感谢,现在都是有道理的。 – Stormherz 2011-12-26 17:11:37

2

你不分配任何东西,所以你不必发布一些东西。

您可以在创建对象时自动释放对象。

YourClass *yourOblect = [YourClass alloc] initWithId:27] autorelease]; 
[yourObject doSomething]; 
..... 
+0

谢谢,我现在明白了=) – Stormherz 2011-12-26 17:13:46