@synchronized は相互排他を実現するために「ロック」と「ロック解除」を使用しませんか? その場合、ロック/ロック解除はどのように行うのですか?
次のプログラムの出力は「Hello World」のみです。
@interface MyLock: NSLock<NSLocking>
@end
@implementation MyLock
- (id)init {
return [super init];
}
- (void)lock {
NSLog(@"before lock");
[super lock];
NSLog(@"after lock");
}
- (void)unlock {
NSLog(@"before unlock");
[super unlock];
NSLog(@"after unlock");
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
MyLock *lock = [[MyLock new] autorelease];
@synchronized(lock) {
NSLog(@"Hello World");
}
[pool drain];
}
ベストアンサー1
Objective-C 言語レベルの同期NSLock
では、 と同様に、ミューテックスが使用されます。意味的には若干の技術的な違いがありますが、基本的には、共通の (よりプリミティブな) エンティティ上に実装された 2 つの個別のインターフェイスと考えるのが正しいです。
特に、 ではNSLock
明示的なロックが行われますが、 では、@synchronized
同期に使用しているオブジェクトに関連付けられた暗黙的なロックが行われます。言語レベルのロックの利点は、コンパイラがそれを理解し、スコープの問題に対処できることですが、機械的には基本的に同じように動作します。
@synchronized
コンパイラの書き換えとして考えることができます:
- (NSString *)myString {
@synchronized(self) {
return [[myString retain] autorelease];
}
}
次のように変換されます。
- (NSString *)myString {
NSString *retval = nil;
pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self);
pthread_mutex_lock(self_mutex);
retval = [[myString retain] autorelease];
pthread_mutex_unlock(self_mutex);
return retval;
}
実際の変換はより複雑で再帰ロックを使用するため、これは正確には正しくありませんが、要点は伝わるはずです。