2014-02-18 34 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