首页 文章

如何在Objective-C中锁定/解锁@synchronized?

提问于
浏览
190

@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];
}

5 回答

  • -3

    Objective-C语言级同步使用互斥锁,就像 NSLock 一样 . 从语义上讲,存在一些小的技术差异,但将它们视为在公共(更原始)实体之上实现的两个独立接口基本上是正确的 .

    特别是对于 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;
    }
    

    这不完全正确,因为实际的转换更复杂并使用递归锁,但它应该得到重点 .

  • 38

    在Objective-C中, @synchronized 块会自动为您处理锁定和解锁(以及可能的异常) . 运行时动态地生成一个NSRecursiveLock,它与您正在同步的对象相关联 . This Apple documentation更详细地解释了它 . 这就是为什么你没有看到NSLock子类的日志消息 - 你同步的对象可以是任何东西,而不仅仅是一个NSLock .

    基本上, @synchronized (...) 是一种简化代码的便捷结构 . 像大多数简化的抽象一样,它具有相关的开销(将其视为隐藏成本),并且很好地意识到这一点,但是无论如何使用这样的构造时,原始性能可能不是最高目标 .

  • 31

    其实

    {
      @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>
    
  • 1

    Apple的@synchronized实现是开源的,可以找到here . Mike Ash写了两篇关于这个主题的非常有趣的帖子:

    简而言之,它有一个表,用于将对象指针(使用其内存地址作为键)映射到 pthread_mutex_t 锁,这些锁根据需要锁定和解锁 .

  • 307

    它只是将信号量与每个对象相关联,并使用它 .

相关问题