(Objective-C)在类方法中重新定义self是否安全?

时间:2011-04-06 09:45:38

标签: objective-c pointers initialization self

在类方法中重新初始化是否安全?

MyClass * a = [[MyClass alloc]init];

@implementation MyClass
{
    -(id)init
    {
        if(self = [super init])
        {
            ...
        }
        return self;
    }
    -(void)redefine
    {
         //??
         self = [self init];

    }

}

a指向重新初始化的MyClass实例吗?

谢谢你, NONONO

3 个答案:

答案 0 :(得分:1)

已提供:(a)您的班级及其超类可以重新init,而不会泄露内存或资源;(b)您知道您的班级及其超类{{ 1}}都返回它们传递的init而不是对其他对象的引用,然后是...

否则会出问题。考虑一下self方法;在这个方法的主体中redefine只是一个局部变量,其内容被初始化为指向某个对象。更改该局部变量中的值不会更改它最初指向的对象,也不会更改指向该对象的任何其他变量的值。例如。考虑变化:

self

显然,这不会改变@implementation Q { - (void) redefine { self = [[Q alloc] init]; // changes the *local* self to refer to a new object } ... } ... Q *someQ = [[Q alloc] init]; // allocate an object [someQ redefine]; // NO effect on someQ, another Q is just created and leaked ,您的版本也可能不会改变。您的代码将具有您希望的效果当且仅当您知道someQ总是返回它传递的对象时 - 这在Obj-C中无法保证。

答案 1 :(得分:0)

只要init返回self(通常情况下就是这样),就不会出错。

但您可能希望将初始化拆分为一些单独的方法,您可以从initredefine调用这些方法。

答案 2 :(得分:0)

您需要从-init返回新对象,而不是简单地为self分配新值。你必须记得释放旧的自我,因为它是用+alloc创建的。除了警告之外,明确允许从-init返回不同的对象。这就是为什么当他们写这样的东西时你会看到新手被纠正的原因:

// Bad example! Do NOT do this!
Foo *foo = [Foo alloc];
[foo init];

这是一种反模式,因为-init 需要返回它所调用的同一个对象。这意味着上面的内容最终可以指定foo指向已释放的对象,而不是指向在其位置初始化的对象。这就是为什么你总是看到+alloc`init链接在一起的原因:

Foo *foo = [[Foo alloc] init];

这也是为什么你在调用super -init时需要重新分配自己的原因,因为它也可能返回了另一个对象。

self = [super init];