开发者

(Objective-C)Is it safe to redefine self within class method?

Is it safe to reinitialise self within a class method?

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

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

    }

}

will a point to the reinitialized开发者_开发问答 instance of MyClass?

Thank You, nonono


Provided that (a) your class and its superclasses can be re-init'ed without leaking memory or resources and (b) you know that your class and its superclasses inits all return the self they are passed and not a reference to some other object, then yes...

Otherwise things will go wrong. Consider your redefine method; in the body of this method self is just a local variable whose contents is initialized to point to some object. Changing the value in that local variable does not change the object it originally pointed at, or the value of any other variables which point to that object. E.g. consider the variation:

@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

Clearly this does not alter someQ, and your version may not either. Your code will have the effect you wish if and only if you know init always returns the object it was passed - which is not guaranteed in Obj-C.


As long as init returns self, which it normally does, nothing will go wrong.

But you probably want to split your initialization to some separate method, which you can call from both init and redefine.


You need to return your new object from -init, not simply assign a new value to self. And you must remember to release the old self, since it was created with +alloc. Caveats aside though, returning a different object from -init is explicitly allowed. That's why you'll see newbies being corrected when they write something like this:

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

This is an anti-pattern because -init is not required to return the same object it was called on. That means the above can end up assigning foo to point to an object that's been released, instead of to the object that was initialized in its place. This is why you always see +alloc and `init chained together like so:

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

It's also why you need to reassign self when calling super's -init, because it may also have returned a different object.

self = [super init];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜