2014-02-18 23 views
2

Apple的开发人员参考指出,如果没有强引用,则释放对象。如果从弱引用调用的实例方法处于执行过程中,会发生这种情况吗?iOS - 执行期间的对象释放

例如,请考虑下面的代码片段 -

@interface ExampleObject 

- doSomething; 

@end 


@interface StrongCaller 
@property ExampleObject *strong; 
@end 

@implementation StrongCaller 


- initWithExampleInstance:(ExampleObject *) example 
{ 
    _strong = example; 
} 

- doSomething 
{ 
    .... 
    [strong doSomething]; 
    .... 
    strong = nil; 
    .... 
} 

@end 

@interface WeakCaller 
@property (weak) ExampleObject *weak; 
@end 

@implementation WeakCaller 

- initWithExampleInstance:(ExampleObject *) example 
{ 
    _weak = example; 
}  

- doSomething 
{ 
    .... 
    [weak doSomething]; 
    .... 
} 

@end 

现在,在主线程,

ExampleObject *object = [[ExampleObject alloc] init]; 

在线程1,

[[StrongCaller initWithExampleInstance:object] doSomething]; 

在线程2,

[[WeakCaller initWithExampleInstance:object] doSomething]; 

假设主线程不再持有对象的引用,如果强[strong doSomething]正在执行时设置为nil,会发生什么情况?在这种情况下对象GC'ed?

+0

是的,它可以发生在对象的方法调用的中间。潜在的症状是相当不可预测的。 –

+0

好的。这怎么可以避免?此外,这不会使一个弱引用不适合并发编程吗? –

+0

可以通过在某处保留强有力的参考来避免。 –

回答

1

通常,在异步阻塞执行期间发生此问题,因为通过更改逻辑不可能避免此问题。

但是,如果你确定你不想改变逻辑,你可以在你的案例中使用相同的解决方案。你应该这样修改你的方法

- (void) doSomething 
{ 
    Your_Class *pointer = self; //Now this local variable keeps strong reference to self 
    if(pointer != nil){ // self is not deallocated 
     ... your code here 
    } 
    //Here pointer will be deleted and strong reference will be released automatically 
} 
+0

感谢您的回复。对于线程安全的软引用对象的所有方法(包括属性访问器)是否应该这样做?此外,这种行为似乎有点奇怪。作为上述策略,人们可以假设ARC自动在方法中创建一个强有力的参考。这对设计施加了许多限制。 –

+0

自动创建保留/释放对将导致性能显着下降。所以ARC不这样做。是的,这个操作应该在每种方法中完成。自动生成的属性可以声明为原子。 – Avt

+0

正如我写的这个机制也用于块。你可以在这里阅读它http://stackoverflow.com/questions/19018456/ios-blocks-and-strong-weak-references-to-self例如 – Avt