@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];
}
Objective-C言語レベルの同期は、NSLock
が行うように、mutexを使用します。意味的にはいくつかの小さな技術的な違いがありますが、それらを共通の(よりプリミティブな)エンティティの上に実装された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;
}
実際の変換はより複雑で、再帰ロックを使用するため、これは正確ではありませんが、ポイントを取得する必要があります。
Objective-Cでは、@synchronized
ブロックがロックとロック解除(および可能な例外)を自動的に処理します。ランタイムは基本的に、同期しているオブジェクトに関連付けられているNSRecursiveLockを動的に生成します。 このAppleドキュメンテーション でさらに詳しく説明しています。 NSLockサブクラスからのログメッセージが表示されないのはこのためです。同期するオブジェクトは、NSLockだけでなく、何でもかまいません。
基本的に、@synchronized (...)
はコードを合理化する便利な構造です。最も単純化された抽象化と同様に、オーバーヘッド(隠されたコストと考えてください)が関連付けられていることに注意してください。
実は
{
@synchronized(self) {
return [[myString retain] autorelease];
}
}
に直接変換します:
// needs #import <objc/objc-sync.h>
{
objc_sync_enter(self)
id retVal = [[myString retain] autorelease];
objc_sync_exit(self);
return retVal;
}
このAPIはiOS 2.0以降で使用でき、...
#import <objc/objc-sync.h>
Appleの@synchronizedの実装はオープンソースであり、 here にあります。マイク・アッシュは、このテーマに関する2つの非常に興味深い投稿を書いています。
簡単に言うと、オブジェクトポインター(キーとしてメモリアドレスを使用)をpthread_mutex_t
ロックにマップするテーブルがあり、必要に応じてロックおよびロック解除されます。