Will this RAII Objective-C-style class work?

In C ++, I have a Mutex class, and I use this RAII style class to ensure that the mutex is unlocked, regardless of the reason the method returns:

 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, the equivalent Objective-C class will not work:

 @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 

What can be used as follows:

 NSLock *_lock; // instance variable - (void)myFunc { Locker *locker = [[Locker alloc] init]; locker.lock = _lock; return; // Whenever I like } 

I understand that this will not work in the case of Objective-C exceptions, unlike the C ++ version, but if all Objective-C exceptions are fatal, I am not worried about that.

UPDATE Just tapped a quick test, and it seems to be working fine. See gist .

+7
c ++ objective-c mutex raii
source share
3 answers

I would say that class methods like

 + (Locker *)lockerWithLock:(NSLock *)lock; 

will probably make ARC auto-detect the return value (see this article ). I think it will be auto-implemented if the method name does not start with alloc , new , init , copy , mutableCopy (or if you do not use special macros to force the compiler to not auto-implement, NS_RETURNS_RETAINED ), clang ARC documentation is pretty good . An autorealized object will obviously be a problem, since your lock will not be unlocked until the autoresist pool is deleted.

I always thought of RAII as C / C ++, where you can allocate objects statically. But I think you can do it this way, as long as you make sure that objects are not auto-implemented.

+3
source share

Best API: use block:

 void performBlockWithLock(NSLock *lock, void (^block)(void)) { [lock lock]; block(); [lock unlock]; } 

Example:

 NSLock *someLock = ...; performBlockWithLock(someLock, ^{ // your code here }); 
+7
source share

If you need RAII patterns, you should use Objective-C ++ and write C ++ RAII classes.

ARC is unlikely to give you the result you want. An object may be released too late if something makes it auto-implement. An object may be released too soon if the ARC optimizer decides that the object is no longer in use.

+4
source share

All Articles