Under C++, I have a Mutex
class, and I use this RAII-style class to ensure the mutex is unlocked, regardless of the reason for the method return:
在c++下,我有一个互斥对象类,我使用这个raii样式的类来确保互斥对象是解锁的,不管方法返回的原因是什么:
class MutexLock {
protected:
Mutex &m_mutex;
public:
MutexLock(Mutex &mutex) :
m_mutex(mutex) {
m_mutex.lock();
}
~MutexLock() {
m_mutex.unlock();
}
};
Is there any reason, and when using ARC, that an equivalent Objective-C class wouldn't work just as well:
是否有任何原因,当使用ARC时,一个等价的Objective-C类不能正常工作:
@interface Locker : NSObject {
NSLock *_lock;
}
- (void)setLock:(NSLock *)lock;
@end
@implementation Locker
- (void)setLock:(NSLock *)lock {
[_lock unlock];
_lock = lock;
[_lock lock];
}
- (void)dealloc {
self.lock = nil;
}
@end
Which might be used in the following way:
可以下列方式使用:
NSLock *_lock; // instance variable
- (void)myFunc {
Locker *locker = [[Locker alloc] init];
locker.lock = _lock;
return; // Whenever I like
}
I understand it won't work in the case of Objective-C exceptions, unlike the C++ version, but assuming all Objective-C exceptions are fatal, I'm not worried about that.
我理解它在Objective-C异常的情况下不起作用,不像c++版本,但是假设所有Objective-C异常都是致命的,我不担心这个。
UPDATE Just knocked-up a quick test, and it appears to be working fine. See this gist.
更新刚刚打结了一个快速测试,它似乎运行良好。看到这个要点。
3 个解决方案
#1
3
I would say that class methods like
我认为类方法
+ (Locker *)lockerWithLock:(NSLock *)lock;
would probably cause ARC to autorelease the return value (see this article). I think it will be autoreleased unless the method name begins with alloc
, new
, init
, copy
, mutableCopy
(or unless you use special macros to force the compiler into not autoreleasing, NS_RETURNS_RETAINED), the clang ARC documentation is pretty good. An autoreleased object would obviously be a problem given your lock wouldn't be unlocked until the autorelease pool is drained.
可能会导致ARC自动发送返回值(参见本文)。我认为它将自动加载,除非方法名以alloc、new、init、copy、mutableCopy开头(或者除非使用特殊的宏来强制编译器不自动发出、ns_returns_retain), clang ARC文档相当不错。一个自动共享的对象显然是一个问题,因为在自动共享池耗尽之前,您的锁不会被解锁。
I always thought of RAII as being a C/C++ thing where you can allocate objects statically. But I guess you can do it this way, as long as you make well sure that the objects are not autoreleased.
我一直认为RAII是一个C/ c++的东西,你可以静态地分配对象。但是我猜你可以这样做,只要你确保对象不是自动加载的。
#2
7
Better API: use a block:
更好的API:使用block:
void performBlockWithLock(NSLock *lock, void (^block)(void)) {
[lock lock];
block();
[lock unlock];
}
Example:
例子:
NSLock *someLock = ...;
performBlockWithLock(someLock, ^{
// your code here
});
#3
4
If you want RAII patterns, you should use Objective-C++ and write C++ RAII classes.
如果您想要使用RAII模式,您应该使用objective - c++并编写c++ RAII类。
ARC is unlikely to give you the result you want. The object may be deallocated too late, if something causes it to be autoreleased. The object may be deallocated too early, if the ARC optimizer decides the object is no longer used.
ARC不太可能给你你想要的结果。如果某物使其发生自动变位,则该对象可能被释放得太晚。如果ARC优化器决定不再使用该对象,则可能太早释放该对象。
#1
3
I would say that class methods like
我认为类方法
+ (Locker *)lockerWithLock:(NSLock *)lock;
would probably cause ARC to autorelease the return value (see this article). I think it will be autoreleased unless the method name begins with alloc
, new
, init
, copy
, mutableCopy
(or unless you use special macros to force the compiler into not autoreleasing, NS_RETURNS_RETAINED), the clang ARC documentation is pretty good. An autoreleased object would obviously be a problem given your lock wouldn't be unlocked until the autorelease pool is drained.
可能会导致ARC自动发送返回值(参见本文)。我认为它将自动加载,除非方法名以alloc、new、init、copy、mutableCopy开头(或者除非使用特殊的宏来强制编译器不自动发出、ns_returns_retain), clang ARC文档相当不错。一个自动共享的对象显然是一个问题,因为在自动共享池耗尽之前,您的锁不会被解锁。
I always thought of RAII as being a C/C++ thing where you can allocate objects statically. But I guess you can do it this way, as long as you make well sure that the objects are not autoreleased.
我一直认为RAII是一个C/ c++的东西,你可以静态地分配对象。但是我猜你可以这样做,只要你确保对象不是自动加载的。
#2
7
Better API: use a block:
更好的API:使用block:
void performBlockWithLock(NSLock *lock, void (^block)(void)) {
[lock lock];
block();
[lock unlock];
}
Example:
例子:
NSLock *someLock = ...;
performBlockWithLock(someLock, ^{
// your code here
});
#3
4
If you want RAII patterns, you should use Objective-C++ and write C++ RAII classes.
如果您想要使用RAII模式,您应该使用objective - c++并编写c++ RAII类。
ARC is unlikely to give you the result you want. The object may be deallocated too late, if something causes it to be autoreleased. The object may be deallocated too early, if the ARC optimizer decides the object is no longer used.
ARC不太可能给你你想要的结果。如果某物使其发生自动变位,则该对象可能被释放得太晚。如果ARC优化器决定不再使用该对象,则可能太早释放该对象。