2011-12-19 83 views
1

我是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原子?

回答

5

其实这是不完全正确的

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

你应该写简单

self.obj = nil; 

这将调用将释放前一个实例的制定者。

+0

谢谢你。有意义 – 2011-12-19 20:48:04

+0

如果在obj属性上未设置nonatomic属性,则这是正确的。 http://developer.apple。com/library/mac /#documentation/Cocoa/Conceptual/ObjectiveC /章节/ ocProperties.html – Joel 2011-12-19 20:59:49

+0

是的,我明白了..看下面我的评论@DBD的帖子。我使这些属性不是原子的。谢谢你:) – 2011-12-19 21:51:44

1

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

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

只要可能访问该变量的任何其他线程也大约在同一锁对象同步,你不应该遇到任何问题。

+1

好点。谢谢,但我把它的财产设置为原子,如下所述。 – 2011-12-19 20:49:00

+0

发送'release'到访问者调用的结果并不是最好的主意。见:http://stackoverflow.com/questions/7262268/why-shouldnt-i-use-the-getter-to-release-a-property-in-objective-c – 2011-12-19 21:59:35

4

是的,它可能会炸毁。考虑你的代码示例。

[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返回或设置的值总是完全收回或无论其他线程正在同时执行什么设置。

+0

谢谢,我有一个你的选择和安德斯的答案上面的组合。我将使用** self.obj = nil; **将调用setter来释放旧值。另外,我会设置@property像你说的那样是原子的。我选择了他的回答tho ..只有一个正确答案可以选择>< – 2011-12-19 20:47:30

相关问题