简体   繁体   中英

Objective-C method to nullify object

i have some trouble writing a method in Objective-C to make an object nil. Here is some example:

@interface testA : NSObject
{
     NSString *a;
}

@property (nonatomic, retain) NSString *a;

+(testA*)initWithA:(NSString *)aString;

-(void)displayA;
-(void)nillify;
@end

@implementation testA
@synthesize a;
+(testA*)initWithA:(NSString *)aString{
    testA *tst=[[testA alloc] init];
    tst.a=aString;
    return [tst autorelease];
}
-(void)displayA{
    NSLog(@"%@",self.a);    
}
-(void)nillify{
    self=nil;
}
- (void)dealloc {
    [a release];
    [super dealloc];
}
@end

int main(int argc, char **argv){
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    testA *test=[testA initWithA:@"some test"];
    [test displayA];
    test=nil;
    //[test nillify];

    NSLog(@"after setting to nil");

    [test displayA];
    [pool release];
    return 0;
}

Apparently, when I set test object to nil and then call some method on it nothing happens, but if i call nillify instead of directly setting it to nil, displayA method works normally like test object is still there. Is there a workaround for nillify method to function properly?

Your help is much appreciated !

You can't actually do something like this, because setting 'self' to nil only has any effect within the scope of that method (in your case, 'nilify'). You don't have any actual way to effect the values of pointers located on other parts of the stack or in random places in the heap, for example.

Basically any code that holds a reference to some object is responsible for maintaining and clearing those references itself. If you have some use case where random sections of code may need references to "live" objects of some kind, but where you'd want those object references to go away in response to some external event (maybe a user tracking system or something), you could do something with notifications, but the various modules tracking those "live" objects would still be responsible for listening for notifications and cleaning up references when they received them.

The 'nilify' thing, however, can't possibly work.

You cannot do what you're trying to do. self is just a local reference to an object that actually exists elsewhere. Setting it to nil doesn't mean anything. An object doesn't, in general, own itself, and it certainly doesn't control other objects' references to it. It's up to the owning objects to manage its lifetime.

There are a few things wrong with your code.

First, by convention, class names start with an uppercase letter. Please stick to these naming conventions as it will make it harder for other developers to work with your code (and even confuse you).

Next, your initWithName: ... According to the naming conventions, a method with init in its name should be an instance method, not a class method. So either name it newWithName: or turn it into an instance method like this:

-(testA*)initWithA:(NSString *)aString{
    self = [super init];
    if (!self) return nil;
    tst.a=aString;
    return self;
}

If you keep it as class method (and name it newWithName: ) you should not return a autoreleased object since according to the naming conventions method that start with init... or new... return a retained object. If you do not follow these conventions, the static analyzer will give you "false" warnings and it will become useless for you.

Now for the reason your nillify doesn't work: the self is in fact an argument to a method. Under the hood, your nillify method actually has two arguments that you do not see: the self pointer and the selector pointer. This means, self is actually a variable on the stack. And if you overwrite it, you only overwrite that stack variable but that doesn't influence your test variable which is somewhere else.

As an example, consider a method - (void)foo:(NSString *)bar; . The compiler turns it into the equivalent of the C function (void) foo(id self, SEL _cmd, NSString *bar) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM