在我目前的項目中,幾個視圖控制器(如vc
)產生在靜態NSOperationQueue上執行的NSOperation對象(如operation
)。當操作正在等待或運行時,它將通過委派報告給視圖控制器(operation.delegate = vc
,分配未保留)。如何正確處理一個排隊代理的排隊nsoperation
雖然這些操作可能需要一段時間,但同時應用程序可以通過彈出導航控制器的堆棧來釋放視圖控制器。
到目前爲止,一切都是故意的。包含靜態NSOperationQueue的類有辦法恢復操作,因此視圖控制器不保留它們。他們只是alloc/init/autoreleased並放在隊列中。
現在,這也會導致問題。在視圖控制器釋放後,任何對NSOperation的激進委託的調用都會導致訪問衝突。據我所知,不可能檢查指針上的對象是否已被釋放,as stated in this question。
我能想到的一個修復方法是保留操作並將操作設置爲dealloc。但那是我最不喜歡的解決方案,因爲它會引入很多額外的ivars /屬性來跟蹤。
因此,我的問題是,還有其他方法來解決這個問題,如果是的話,你能在這裏畫一個嗎?
乾杯,
EP。
SOLUTION:制定出最適合我的方法是朱利安諾的回答略有變化:
實現隊列管理器每個代表協議是不可行的(20個+不同的協議與50+方法),所以我保留了直接委託分配。我所做的改變是讓班級進行分配。這曾經是創建請求的類(和委託),但現在它被卸載到隊列管理器。
隊列管理器在將委託分配給操作旁邊還包含輔助可變字典以跟蹤委託/操作對。
每個委託實例在釋放時調用
[QueueManager invalidateDelegate:self]
方法,然後查找屬於該委託的請求並將其刪除。然後字典操作/委託對也被刪除,以允許適當地釋放該操作。最後,在KVO觀察每個操作的
isFinished
屬性後,可變字典保持清晰,以確保所有操作保留計數實際上在完成後釋放。
感謝Guiliano提供了使用KVO來解決這個問題的提示!
+1其次。它還可以更容易地「重新連接」到vc,以防再次出現並需要響應隊列(及其內容)中的更改。 – Toastor 2011-05-06 17:04:29
非常有趣的方法。它將使QueueManager(確實存在)更加複雜一點,但它也將使代表團更加健壯。我會讓它醃一下,但聽起來像是要走的路。 – epologee 2011-05-06 17:24:59
如果您需要一些示例代碼,請參閱Apple文檔中的FetchedImageLinker示例代碼。有一個名爲WatchedOperationQueue的類(或類似的東西,這裏沒有文檔)實現了描述的行爲。 – 2011-05-06 19:48:32