[問題] Delegate Callback與Main Thread的問題
各位好,
最近在寫一個架構上出了點問題,想要請教一下
問題:
如何在background thread觸法一個應在main thread上執行的delegate callback,
且在delegate dealloc的時候,可清掉已註冊在main runloop上卻還沒被執行的callback
問題完整版:
問題是這樣的,我寫了一個會自行跟伺服器抓圖的Class A,
實體化後的Object A會運行在他自己開的Thread上,
並且會提供一個delegate callback,把抓到的圖丟回給delegate
然後我又寫了一個UIView B,並把他註冊為Object A的delegate
但是這樣一來,如果在B實作的callback裡直接把圖畫到畫面上,
就一定得自己在main thread上呼叫一次display畫面才會更新(因為在A的thread)
所以我想說,若是Class A在觸法delegate的callback的時候,
直接在main thread上觸法就好,
於是我就在Class A用了performSelectorOnMainThread方法來觸法callback,
但是這樣卻又會出現一個問題,就是如果某一天我把UIView B殺掉後,
main runloop上卻還有來不及被執行的callback的話,就會造成EXC_BAD_ACCESS...
目前我想到的解決的辦法
1. 設定performOnMainThread 的 waitUntilDone 為 YES
但是這會block住抓圖的thread, 這樣另外開thread的意義就不是很大
2. 在UIView B dealloc的時候清掉main runloop上以B為對象的callback
或是Object A dealloc的時候,清掉自己發出且還未執行的callback
google了一個早上,好像沒有辦法清掉..(要在同個thread才行)
3. 在B實作的callback裡面自己呼叫更新UI的方法
其實就是想避免這個
想問一下這該如何達成? 感謝各位前輩的提點
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.135.62.74
※ 文章網址: http://www.ptt.cc/bbs/MacDev/M.1417621332.A.4A8.html
→
12/04 00:09, , 1F
12/04 00:09, 1F
感謝提醒,我有在B的dealloc設定A的delegate 為 nil
推
12/04 00:22, , 2F
12/04 00:22, 2F
→
12/04 00:31, , 3F
12/04 00:31, 3F
→
12/04 00:33, , 4F
12/04 00:33, 4F
剛剛試了一下weak property,還是有同樣的問題QQ
下班之後我再附上完整範例
→
12/04 09:02, , 5F
12/04 09:02, 5F
→
12/04 09:02, , 6F
12/04 09:02, 6F
A其實是隸屬於B的一個子元件,並且A會在thread開始與結束時retain/release delegate
然後B會在viewDdidDisappear的時候把A停掉
所以應該是不會有B比A早死的狀況,也不會有同步的問題吧..?我猜
推
12/04 09:10, , 7F
12/04 09:10, 7F
是的,A的程式碼大概長這樣:
// A的Thread method
- (void)threadA {
[delegate_ retain];
while(![NSThread currentThread].isCancelled) {
if (delegate_ && [delegate_ respondsToSelector:@selector(callback)] {
NSMethodSignature *signature =
[(NSObject *)delegate_ methodSignatureForSelector:@selector(callback)];
NSInvocation *invoke =
[NSInvocation invocationWithMethodSignature:signature];
[invoke setTarget:delegate_];
[invoke setSelector:@selector(callback)];
[invoke setArgument:&self atIndext:2];
...
[invoke performSelectorOnMainThread:@selector(invoke)
withObject:nil
waitUintilDone:NO];
}
}
[delegate_ release];
}
// B的dealloc
- (void)dealloc {
[A setDelegate:nil];
[A release];
A = nil;
...
[super dealloc];
}
※ 編輯: Esvent (220.135.62.74), 12/04/2014 10:33:35
→
12/04 10:38, , 8F
12/04 10:38, 8F
→
12/04 10:38, , 9F
12/04 10:38, 9F
→
12/04 10:39, , 10F
12/04 10:39, 10F
→
12/10 19:00, , 11F
12/10 19:00, 11F
→
12/10 19:01, , 12F
12/10 19:01, 12F
→
12/10 19:01, , 13F
12/10 19:01, 13F
MacDev 近期熱門文章
PTT數位生活區 即時熱門文章