Should NSLocking usage always be wrapped in @try/@finally?
Given a Cocoa NSLocking
object (like an N开发者_如何学运维SLock
) and some non-trivial code to be executed while the lock is held:
To ensure a lock is always released, should the following idiom always be used?
NSLock *mutex = // get lock from somewhere
@try {
[mutex lock];
// do non-trivial stuff
}
@finally {
[mutex unlock];
}
This seems prudent (and common in Java), but I haven't seen any Cocoa code do this.
Should this idiom be used? Why or why not?
To ensure a lock is always released, should the following idiom always be used?
Yes, where program correctness after that scope ('non-trivial stuff') is required, and assuming your program can properly recover from the exceptions it encounters.
Should this idiom be used? Why or why not?
If you can recover, then yes, unlocking is necessary to continue execution normally. Otherwise, your program will be executing in an invalid state.
Example 1: When the lock is destroyed (during
dealloc
), the attempt to destroy it will fail because it is still locked. Whether the implementation continues to destroy the lock or ignores the error is not defined (I would guess it would persist, meaning it would never exit fromdealloc
).Example 2: When it is locked from another thread (or the same thread, if not reentrant) then you will never acquire the lock and another error, deadlock, or exception may be produced as a result. An implementation could also (eventually) proceed with no lock acquired. All that is guaranteed is logging when/if an error is detected.
pthread_mutex
es and the implementations that depend on them may not behave very gracefully if you have such a lock imbalance; this always falls back to a programmer error.
Correct and defensive locking in pure objc and c is not very pretty. The Java idiom is correct, and equally applicable to Foundation APIs. The reason you don't see it as much may be because exceptions are a less popular/used error handling mechanism within Cocoa APIs and programs that depend on them (compared to Java). see also Bavarious' note in the comments
No.
Exceptions are only used for programming errors in Cocoa. They are not used for situations where the program is expected to recover.
精彩评论