【问题标题】:what does it mean to declare a NSNumber variable as property copy将 NSNumber 变量声明为属性副本是什么意思
【发布时间】:2011-12-07 00:23:47
【问题描述】:

我还在学习...,所以对于以下属性

@property (copy) NSNumber *foo;

副本的真正作用是什么?复制 foo 的(值)并将其放到新位置?就像复制构造函数一样?

而且还要澄清一下,下面基本上是在做一个AddRef,对吧?

@property (retain) NSNumber *foo;

【问题讨论】:

    标签: objective-c copy properties retain


    【解决方案1】:

    请参阅此处的属性说明: http://cocoacast.com/?q=node/103

    copy 表示给属性赋值会复制输入值。

    retain 表示您不会获得实际副本;你会得到相同的对象,上面有一个额外的保留。因此,如果它在其他地方进行了修改,您会在这两个地方看到修改。

    对于NSNumbers,它们是不可变的,因此复制和保留在功能上是等效的。

    【讨论】:

      【解决方案2】:

      文案的真正作用是什么?

      一般来说,NSNumber 是不可变的——我希望在这些情况下copy 将使用retain 实现:

      - (id)copyWithZone:(NSZone*)zone {
        return [self retain];
      }
      

      而且还要澄清一下,下面基本上是在做一个AddRef,对吧?

      好吧,合成它会添加引用计数样板 - 实际操作更复杂并采用通用形式:

      - (void)setFoo:(NSNumber *)arg {
        NSNumber * prev = foo;
        foo = [arg retain]; // << or foo = [arg copy]; if you have specified 'copy'
        [prev release];
      }
      

      【讨论】:

      • 当然,如果您使用非原子与原子,则样板会发生变化。 nonatomic 更接近上述代码。由于您没有指定非原子,因此在后台也会发生 @synchronize 调用。 stackoverflow.com/questions/588866/…
      • 非原子 ==> 代码只会从单个线程调用。如果没有 nonatomic 关键字,代码是 more 线程安全的,或者更好的想法是您能够使用原子 getter 和 setter 编写线程安全代码。
      • @Tom Anderson 是的,我知道该示例类似于非原子实现(但您的示例对其他人来说是一个很好的说明)。这是什么原因?这是一个初学者的 Cocoa 问题,我说这个例子是正在发生的事情的 概括 形式(在问题的上下文中)。
      • 关于您的其他 cmets 的一些注意事项:1) 非原子属性可以是线程安全的,并且它们可以在多线程上下文中运行。毕竟,在 ObjC-V2 之前,我们能够创建线程安全的并发 Cocoa 程序。 2) 原子属性@synchronized 实现。这是一个流行的误解——这也意味着 a) 使用 @synchronized 和 b) 期望原子属性实现也将使用它们的程序有许多并发设计错误等待被发现。 (续)
      • (cont) 3) 原子属性根本不能替代适当的线程安全。它们仅在非常有限的范围内保护数据。毫无疑问,仅原子属性在并发执行中仍然是不安全的——它们只会降低线程错误在执行期间发生(或暴露)的可能性。这甚至是不可取的 - IMO,我宁愿这个缺陷更早地暴露出来并且更频繁地发生,因为并发程序中的错误可能非常难以重现。 (续)
      猜你喜欢
      • 2021-12-16
      • 1970-01-01
      • 2010-09-19
      • 2016-12-14
      • 2013-02-08
      • 1970-01-01
      • 2022-12-15
      • 1970-01-01
      • 2014-09-20
      相关资源
      最近更新 更多