NSLock“控制器”班级
我正在为 iPhone 编写一个多线程应用程序,并且使用 NSLock 来确保某些操作(例如从文件加载声音)将表现为原子操作。为了简化从应用程序的不同部分获取锁,我编写了以下类,它让我只需传递带有名称的 NSString 即可锁定和解锁锁。如果这样的锁不存在,它会创建它并保存以供将来使用。 我测试了它,它似乎工作正常(因为它只提供对 NSLock 对象的访问,并且不会改变它们的行为)。
我的问题是:拥有和使用这样的类可以吗,还是我对锁的概念有一些误解?
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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这对我来说看起来相当沉重。你确定不能简化设计吗? (我想到了 GCD。)几乎每个 iOS 应用程序都是多线程应用程序,恕我直言,很少看到像您编写的这样的锁定助手。如果说KISS 原则有什么亮点的话,我确信那就是多线程。
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.
@synchronized
很慢,避免使用它。在+initialize
中分配一个锁并使用它。但我会选择单例而不是使用类方法,但这或多或少是一个品味问题。您的方法的主要缺点是您必须锁定一个锁才能获得另一个锁。在高度多线程的应用程序中,即使线程都想要访问不同的锁,此元锁(当前的
@synchronized
)也可能成为性能瓶颈。@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.