【问题标题】:Should releasing an object and setting it to nil be atomic?释放一个对象并将其设置为 nil 是否应该是原子的?
【发布时间】:2011-12-19 20:01:12
【问题描述】:

我是 Objective C 的新手。我在许多 iPhone/iPad 应用程序中看到,在释放一个对象后,它会被设置为 nil。

[self.obj release]
self.obj = nil; 

我认为这样做是为了不让指针指向现在已释放的内存位置。现在假设以下情况:

//Thread #1 code
..some code
..some code
[self.obj release]
                  -------> Thread #2 runs //Thread #2 code
                                          ..some code
                                          if (self.obj){
                                            some code
                                          }
self.obj = nil;   <----- Thread #1 runs

我想知道这种情况是否可能?如果是,有没有办法使 release/nil 成为原子的?

【问题讨论】:

    标签: objective-c ios multithreading cocoa-touch


    【解决方案1】:

    这其实并不完全正确

    [self.obj release]
    self.obj = nil;
    

    你应该写简单

    self.obj = nil;
    

    这将调用将释放前一个实例的设置器。

    【讨论】:

    【解决方案2】:

    是的,它可能会爆炸。考虑您的代码示例。

    [self.obj release];
    self.obj = nil;
    

    您使用self.obj,这意味着您正在引用访问器/修改器方法,而不是直接访问您的对象。您可能会将“obj”声明为保留属性。您的 .h 将类似于...

    @property (retain) Something *obj;
    

    还有你的 .m

    @synthesize obj;
    

    如果您稍后使用 @synthesize 创建的方法释放您的对象,您是安全的。

    [self setObj:nil];
    // or equally valid
    self.obj = nil;
    // Below is (almost) identical way to access, release and nil the variable directly.
    // The major difference is you don't multi-threaded protection of your property
    // declaration (explained below).
    [obj release];
    obj = nil;
    

    如果你回顾我上面指定的属性,你会发现我没有输入非常常见的nonatomic。这不是偶然的。看看苹果的docs

    默认情况下,属性是原子的,因此综合访问器在多线程环境中提供对属性的稳健访问——也就是说,无论其他线程同时执行什么,从 getter 返回或通过 setter 设置的值始终被完全检索或设置.

    【讨论】:

    • 谢谢,我选择了您和安德斯在上面的答案的组合。我将使用 self.obj = nil; 这将调用 setter 来释放旧值。另外,我会将@property 设置为像你说的那样是原子的。我选择了他的答案。。只能选择一个正确答案>
    【解决方案3】:

    您可以将这两个操作都包含在一个 @synchronized 块中,以确保两个操作在离开该块之前完成:

    @synchronized(lockObject)
    {
        [self.obj release];
        self.obj = nil;
    }
    

    假设任何其他可能访问该变量的线程也围绕同一个锁对象进行同步,您应该不会遇到任何问题。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-06
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多