开发者

NSLock "controller" class

I'm writing a multithreaded application for iPhone, and I'm using NSLock's to make sure that some operations (such as loading sounds from file) will behave as atomic. To simplify acquiring locks from different parts of my application, I wrote following class, that lets me lock and unlock locks just by passing NSString with name. If such lock doesn't exist, it creates it and saves for future. I tested it and it seems to work fine (as it just provides access to NSLock objects and doesn't alter their behavior).

My question is: Is it ok to have and use such class, or do I have some misunderstanding in concept of locks?

Locker.h

#import <Foundation/Foundation.h>

@interface Locker : NSObject { }

+ (void) purgeLocks;
+ (NSLock*) lockWithName: (NSString*) name;
+ (void) lock: (NSString*) name;
+ (void) unlock: (NSString*) name;
+ (BOOL) tryLock: (NSString*) name;

@end



Locker.m

#import "Locker.h"

static NSMutableDictionary* locks = nil;

@implementation Locker

+ (void) initialize {
    locks = [[NSMutableDictionary dictionary] retain];
}

+ (void) purgeLocks {
    [locks release];
    [Locker initialize];
}

+ (NSLock*) lockWithName: (NSString*) name {
    NSLock* lock = nil;
    @synchronized([Locker class]) {
    开发者_运维百科    lock = [locks objectForKey: name];
        if(!lock) {
            lock = [[[NSLock alloc] init] autorelease];
            [lock setName: name];
            [locks setObject: lock forKey: name];
        }
    }
    return lock;
}

+ (void) lock: (NSString*) name {
    [[Locker lockWithName: name] lock];
}

+ (void) unlock: (NSString*) name {
    [[Locker lockWithName: name] unlock];
}

+ (BOOL) tryLock: (NSString*) name {
    return [[Locker lockWithName: name] tryLock];
}

@end


@synchronized is slow, avoid it. Allocate a lock in + initialize and use that instead. But I'd go for a singleton instead of using class methods, but that's more or less a matter of taste.

The major drawback to your approach is that you have to lock a lock in order to get another lock. In a heavily multihreaded app this meta-lock (your current @synchronized) can become a performance bottleneck even if the threads all want to access different locks.


This looks quite heavy to me. Are you sure you can’t simplify the design? (GCD comes to mind.) Almost every iOS application is a multithreaded one, and IMHO it’s rare to see such locking helpers as you have written. If there’s a place where the KISS principle shines, I’m sure it’s multithreading.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜