【问题标题】:Objective-C: releasing the object from itselfObjective-C:从自身释放对象
【发布时间】:2011-07-08 14:10:42
【问题描述】:

我偶然发现了一个有趣的情况,当对象可以释放自己时,我想知道在这种情况下什么被认为是安全和正确的。

假设我们有一个类 Foo:

@implementation Foo
+ (Foo *) foo {
    return [[[Foo alloc] init] autorelease];
}

- (void)resign {
    [FooHolder holder].foo = nil;

    // here's where the things happen
}
@end

另一个类是 FooHolder(具有一个属性的单例):

@interface FooHolder : NSObject {
    Foo *foo;
}

@property (retain) Foo *foo;

+ (FooHolder *)holder;

@end

我们在代码中的某处执行此操作(首先调用stepOne,然后调用stepTwo;自动释放池在stepOne 完成后耗尽):

- (void)stepOne {
    Foo *foo = [Foo foo];

    [FooHolder holder].foo = foo;
}

- (void)stepTwo {
    [[FooHolder holder].foo resign]
}

如果我尝试在resign 方法中访问self,在分配后,使用NSZombieEnabled,我会收到self 已被释放的警告。这给了我短暂的 WTF 时刻,但是好吧,我可以在这部分不访问 self 生活。更让我烦恼的是,如果对象已经被释放,谁能保证堆栈没有损坏,并且我们正在正常处理我们的本地和实例变量?一般来说,在方法中允许self 被释放是一种不好的做法吗?

【问题讨论】:

  • 点的特殊用法看起来很丑;我建议只使用常规方法调用语法。

标签: objective-c


【解决方案1】:

一般来说,在方法中允许释放 self 是一种不好的做法吗?

是的,因为从释放 self 的角度来看,您的所有 ivars 也可能被释放。

我不会假装理解你的设计或你这样做的原因,但你为什么不重新安排你的辞职方式:

- (void)resign {
    // here's where the things should happen
    [FooHolder holder].foo = nil;
}

您应该始终释放拥有的对象,因为您有机会使用它们,就像您在-(void)deallocend 处调用 [super dealloc]; 一样

【讨论】:

    【解决方案2】:

    我认为你的设计有缺陷。在实例方法-resign 中,您有效地释放了单例持有的 foo 的特定实例。为什么 foo 的任何 任意 实例都会这样做?在实例方法中引用有效的全局变量会使耦合过于紧密。

    任何调用-resign 的东西都应该是告诉[FooHolder holder] 它已经辞去foo 或将辞去foo 的东西。或者,在foo 中对FooHolder 进行弱引用,并让foo 向其发送类似-willResign:(Foo*) 的消息,这实际上使其成为foo 的代表。在-willResign: 中,FooHolder 可以检查它是否是正确的foo,然后在将其设置为 nil 之前保留并自动释放它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-22
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多