Can an Objective-C object remove its method in its method (ARC enabled)?

For some reason I have to use a design pattern that an object removes from its container, consider the following code (ARC enabled, LCObject is object class, LCDContainer is container class), throughout the program, the object reference count is always 1 as long as it will not be removed from the container (the refcount will become 0) as mentioned in comment 2, when [_container removeObject:self]

return, the object refcount is 0, this is a dealloc, right? but the process still remains in the object method - "removeFromContainer", what happens ? Will the following code run successfully? Can " removeFromContainer

" return successfully?

I am running this code in Xcode, "NSLog" in "removeFromContainer" can be called successfully, but I cannot figure out why ...

//-------------------------------------------------------------
#import <Foundation/Foundation.h>

@interface LCDContainer : NSObject

@property (strong, nonatomic) NSMutableArray *objects;
- (void)removeObject:(id)object;
- (id)addObject:(id)object;

@end

@implementation LCDContainer

- (id)init {
    self = [super init];
    if (self) {
        _objects = [[NSMutableArray alloc] init];
    }
    return self;
}

- (id)addObject:(id)object {
    [_objects addObject:object];
    return object;
}

- (void)removeObject:(id)object {
    [_objects removeObject:object];
}

@end

//-------------------------------------------------------------
@interface LCDObject : NSObject

@property (weak, nonatomic) LCDContainer *container;
- (id)initWithContainer:(LCDContainer*) container;
- (void)removeFromContainer;

@end

@implementation LCDObject

- (id)initWithContainer:(LCDContainer *)container {
    self = [super init];
    if (self) {
        _container = container;
        // (1) add the object to the Container, now its reference count is 1
        //
        [container addObject:self];
        NSLog(@"add to container.");
    }
    return self;
}

- (void)removeFromContainer {
    // (2) remove the object from the Container, now its reference count is 0,
    //     the object is delete, does the following "NSLog" would be invoked successfully? 
    //
    [_container removeObject:self];
    NSLog(@"remove from container.");
}

@end

//-------------------------------------------------------------
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        LCDContainer *container = [[LCDContainer alloc] init];
        [[LCDObject alloc] initWithContainer:container];
        [[[container objects] objectAtIndex:0] removeFromContainer];
    }
    return 0;
}

      

+3


source to share


1 answer


I haven't tried your code, but I suspect it will work. sapi's suggestion (adding a breakpoint or NSLog to dealloc) is a good confirmation.

There are two ways that ARC can do it. You can check out the assembler if you are really interested.

It's easiest to assume what it uses autorelease

, i.e. when an object is removed from your container, it is added to the autostart pool and freed (and freed) at the end of the current run cycle.



Another way is to consider where ARC adds its reserves and releases. This question notes that your delete method looks like this:

- (void)removeObject:(id)object {
    [object retain];
    [_objects removeObject:object];
    [object release];
}

      

The call removeObject:

can have the same logic. This means that the object is not released once the call is removeObject:

complete; the object's lifecycle is almost certainly (slightly) longer.

0


source







All Articles