@synchronized(self)是否创建了一个块,其中self前缀在属性上是不必要的?

22

我在某个外国代码中读到了一些东西,我想检查一下我的假设:

@synchronized(self) 在设置属性时用于摆脱self前缀。

因此,在我的下面的示例中,我设置了实例的strText,而不仅仅是一个局部变量,对吗?

- (void)myfunction{
    NSString * strText = @"var in function";
    @synchronized(self)
    {
         strText = @"var class (self.strText)";
    }

}
3个回答

41
请阅读此 文档

@synchronized()指令锁定一段代码供单个线程使用。其他线程被阻塞,直到该线程退出受保护的代码块,即当执行继续超过@synchronized()块中的最后一个语句时。

@synchronized()指令以其唯一参数作为Objective-C对象,包括self

正如Massimo Cafaro指出的:"在应用程序变成多线程之前创建所有互斥对象是最安全的,以避免竞争条件。"


2
文档链接已过时,请参考以下链接: https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW1 - cescofry
@cescofry,是的,那个链接已经过时了。我用你给出的链接更新了我的答案。谢谢。 - Tirth

8

@synchronized(self)用于消除self.前缀。

所以在我的例子中,我不是在函数中设置strText,而是在类中设置。

两个概念被混淆了。

  1. @synchronized(self) { ... }只锁定使用self对象作为信号量的块。
  2. 在Objective-C中,没有像其他语言那样的假设with语句,可以省略self.whatever变成whatever。建议参加斯坦福大学CS193P在线课程,提高语言水平。

7
为什么会有这样的回答?它或许“回答”了问题,但是——无意冒犯——你的表达显得简洁而没有帮助性。 - Matt Mc
5
@synchronized关键字不会影响是否需要在变量前加上"self."前缀,它们毫无关联。 - Reid Ellis
2
这是三个答案中唯一一个实际上解决了问题中的误解的答案@Matt。其他两个只是机械地引用了有关@ synchronized()的文档。 - jscs
@JoshCaswell 追踪,但我的评论是来自2013年,而在2014年Barry编辑了这篇文章,实际上除了“你错了”之外还说了些什么。我想你是对的,现在这篇文章更好地“回答了问题”。 - Matt Mc
抱歉,马特,我肯定应该想到查看修订历史记录。 - jscs

0
在多线程环境中,如果有多个线程尝试访问相同的内存地址,则可能会导致“竞争条件”。为了避免这种情况,您应该使用“互斥锁(Mutual Exclusion)”,即阻止、限制或锁定n个线程以在同一时间点访问相同的内存地址或内容,并仅允许一个线程在一个时间点。在Objective C中,可以通过使用@synchronized指令来实现这一点。
例如: 通常,在实现Singleton设计模式或类时,您将在任何iOS项目中看到以下代码片段。
+(id)getSingletonInstance
{
    @synchronized(self)
    {
        if (singletonObj == nil)
        {
            singletonObj = [[self alloc] init];
        }
        return singletonObj;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接