我们在使用lock的时候会有这样的情况:因为某方法内部逻辑较为复杂,会有很多地方return,稍不留神都会漏掉一次unlock的操作,在查看一些C++源码时发现一种比较优雅的设计,在某个方法或一个代码块需要锁时,不直接对锁进行操作,而是通过创建一个局部对象来管理这个锁,我们将这个对象称之为”哨兵”,该对象在构造函数中执行lock操作,而在析构函数中执行unlock,这样当我们需要加锁时只需要创建这个对象,当函数return后或代码块结束时,因为局部对象在超出作用域后释放,便自动完成了unlock的动作。
而在Objective-C中我们不能创建局部对象,但利用ARC的特性却也可以达到超出作用域自动释放的特性。
以下是”哨兵”类的实现:
@interface QMGuard : NSObject
{
id<NSLocking> lock;
}
@end
@implementation QMGuard
- (id)initWithLock:(id<NSLocking>)obj
{
self = [super init];
if (self)
{
lock = obj;
[lock lock];
}
return self;
}
- (void)dealloc
{
[lock unlock];
}
@end
以下是我们在使用锁的时候:
//为了方便使用
QMGuard *_guard_ = [[QMGuard alloc] initWithLock:lock];\
NSAssert(_guard_, @"_guard_ invaild");
@interface MyClass : NSObject
{
NSLock *lock;
}
@end
@implementation MyClass
- (id)init
{
self = [super init];
if (self)
{
lock = [[NSLock alloc] init];
}
return self;
}
- (void)test1
{
QUARD(lock)
NSLog(@"do test1");
}
- (void)test2
{
QUARD(lock)
NSLog(@"do test2");
}
@end