Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If a method is called at the exact same time twice, how to only execute it once?

We have a method in the iPhone SDK that is a delegate method. Problem is, the OS calls this method twice at the exact same time. This method does some heavy lifting so I don't want to execute the logic twice. What is a good way to detect this and prevent one of the two from running?


Forgot to mention that, it is called from different threads.

like image 296
erotsppa Avatar asked Oct 02 '09 03:10

erotsppa


1 Answers

One method is a BOOL member that you set when entering the method and clear on leaving it. If the variable is set upon entry, you know it's already executing and can just return.

Assuming you're being called from multiple threads, you'll want to lock access to this critical area of checking/setting. An NSLock is good for this.

The code below has two implementations: myMethod1 which uses NSLock and myMethod2 which shows using @synchronize.

@interface MyClass : NSObject
{
    NSLock* theLock;
    BOOL isRunning;
}
@end

@implementation MyClass

-(id)init
{
    self = [super init];
    if(self != nil)
    {
        theLock = [[NSLock alloc] init];
        isRunning = NO;
    }
    return self;
}

-(void)dealloc
{
    [theLock release];
    [super dealloc];
}

// Use NSLock to guard the critical areas
-(void)myMethod1
{
    [theLock lock];

    if(isRunning == YES)
    {
        [theLock unlock]; // Unlock before returning
        return;
    }

    isRunning = YES;        

    // Do fun stuff here

    isRunning = NO;

    [theLock unlock];    
}

// This method uses @synchronize
-(void)myMethod2
{
    @synchronized(self)
    {
        if(isRunning == YES)
        {
            return;
        }

        isRunning = YES;

        // Do stuff here.

        isRunning = NO;
    }
}
@end
like image 56
nall Avatar answered Nov 05 '22 12:11

nall