Objective c 释放一个对象并将其设置为nil应该是原子的吗?

Objective c 释放一个对象并将其设置为nil应该是原子的吗?,objective-c,ios,multithreading,cocoa-touch,Objective C,Ios,Multithreading,Cocoa Touch,我不熟悉Objective C。我在许多iPhone/iPad应用程序中看到,在发布一个对象后,它会被设置为零 [self.obj release] self.obj = nil; 我假设这样做是为了不让指针引用现在被释放的内存位置。现在假设以下情况: //Thread #1 code ..some code ..some code [self.obj release] -------> Thread #2 runs //Thread #2 code

我不熟悉Objective C。我在许多iPhone/iPad应用程序中看到,在发布一个对象后,它会被设置为零

[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原子化

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

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

如果可能访问该变量的任何其他线程也围绕同一锁定对象进行同步,则不应遇到任何问题。

您可以在@synchronized块中围绕这两个操作,以确保在离开块之前完成这两个操作:

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

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

这实际上并不完全正确

[self.obj release]
self.obj = nil;
你应该写得简单些

self.obj = nil;

它将调用释放上一个实例的setter

这实际上并不完全正确

[self.obj release]
self.obj = nil;
你应该写得简单些

self.obj = nil;

它将调用释放上一个实例的setter

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

[self.obj release];
self.obj = nil;
您使用self.obj,这意味着您引用的是访问器/变异器方法,而不是直接访问对象。您很可能会将obj声明为保留财产。你的h应该是

@property (retain) Something *obj;
还有你的

@synthesize obj;
如果以后使用@synthesis创建的方法释放对象,那么您是安全的

[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;
如果你回顾一下我在上面指定的属性,你会注意到我没有加入非常常见的非原子。这不是偶然的。看看苹果的

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


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

[self.obj release];
self.obj = nil;
您使用self.obj,这意味着您引用的是访问器/变异器方法,而不是直接访问对象。您很可能会将obj声明为保留财产。你的h应该是

@property (retain) Something *obj;
还有你的

@synthesize obj;
如果以后使用@synthesis创建的方法释放对象,那么您是安全的

[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;
如果你回顾一下我在上面指定的属性,你会注意到我没有加入非常常见的非原子。这不是偶然的。看看苹果的

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


谢谢,我选择了你的答案和上面安德斯的答案的组合。我将使用self.obj=nil;它将调用setter来释放旧值。另外,我会像你说的那样将@property设置为原子属性。我选择了他的答案。。只能选择一个正确答案>谢谢,我选择了你的答案和上面安德斯的答案的组合。我将使用self.obj=nil;它将调用setter来释放旧值。另外,我会像你说的那样将@property设置为原子属性。我选择了他的答案。。只能选择一个正确答案>正确答案。谢谢,但我还是按照下面提到的将属性设置为原子属性。向访问器调用的结果发送release不是最好的主意。见:好的观点。谢谢,但我还是按照下面提到的将属性设置为原子属性。向访问器调用的结果发送release不是最好的主意。请参阅:如果未在obj属性上设置非原子属性,则这是正确的。是的,我知道。。请看下面我的评论@DBD的帖子。我将属性设置为非原子属性。tho tho:如果obj属性上没有设置非原子属性,那么这是正确的。是的,我知道。。请看下面我的评论@DBD的帖子。我将属性设置为非原子属性。谢谢你,tho: