Search code examples
objective-csynchronizationlockingdealloc

What is the correct way to dealloc a lock in objective-c


I have created an NSObject, for the sole purpose of locking. My question is, in my dealloc, how do I release(from memory) the lock. I have read that you should not modify the lock-object within synchronized. But In my scenario, I think that between the time since the @synchronized in dealloc completes, and the time that [_lockObject release] is called, another method in a different thread may acquire _lockObject. And hence if [_lockObject release] is called while _lockObject is held, bad things may happen.

What is the correct way to dispose of the lock in my dealloc method?

-(id)initWithImageFileName:(NSString*)imageFileName
{
    if (self = [super init])
    {
        _imageFileName = [imageFileName retain];
        _loadBackgroundCalled = NO;
        _deallocing = NO;
        _lockObject = [[NSObject alloc]init];
    }

    return self;
}

-(void)dealloc
{
    _deallocing = YES;

    @synchronized(_lockObject)
    {
        ..... <releases some stuff>

    }

    [_lockObject release];
    _lockObject = nil;


    [_imageFileName release];
    _imageFileName = nil;

    [super dealloc];
}

-(void)loadBackground
{
    @synchronized(_lockObject)
    {
        if (!_deallocing)
        {
            if (!_loadBackgroundCalled) 
            {
                _loadBackgroundCalled = YES;
                ....
            } 
        }
    }
}

-(void)loadSprite:(XYTexture*)texture
{
    @synchronized(_lockObject)
    {
        ....
    }
}

-(void)unloadBackground
{
    @synchronized(_lockObject)
    {
        if (!_deallocing)
        {
            .....
            _loadBackgroundCalled = NO;
        }
    }
}

Solution

  • Your object cannot be deallocated while it's being used by another object or thread. In other words, any thread that calls your object will already hold a reference to said object, and that reference will prevent the object from deallocating.

    When your -dealloc method is executed you can (and must) assume that no other objects or threads hold a reference to your object, and you therefore do not have to worry about concurrency.

    If -dealloc is called while your object is executing on a separate thread then that would indicate a bug in your application unrelated to this specific object. You do not solve the problem by setting flags like _deallocing, as in your example code.