[英]Update UI on dispatch_get_main_queue()
我有一個問題與使用隊列更新主線程上的UI有關。
好吧,假設我們創建了一個UITableView,它顯示了一個帶有UIImageView的UILabel。 UIImage是在prepareCellfor中異步加載的..使用:
dispatch_async(t_queue, ^{
//load image
//dispatch_async(dispatch_get_main_queue(),^{
cell.imageView = image;
}
});
但是當塊正在獲取圖像時,用戶按下一個單元格(或導航視圖控制器上的后退按鈕),為該單元格加載de DetailViewController(或在應用程序中返回)。
我的問題是:當塊啟動主線程以更新單元格的imageView時會發生什么? 它試圖更新未加載到窗口上的UIView,甚至可以卸載它...
謝謝
這是一個很好的問題。 使用ARC
時的答案主要是塊本身保留了對象,因此它將在以后使用。 這是那些微妙的記憶陷阱之一。 如果取消分配此單元格的UITableView
並釋放其所有單元格,則將保留此單元格(雖然在屏幕外),並且將分配cell.imageView = image;
完成后,它將被釋放。
我是受控實驗的忠實粉絲,並開始測試這個,但UITableView
有許多移動部件(沒有雙關語意)。 所以我創建了一個非常簡單的實驗,使用一個簡單的NSObject
子類,如下所示:
@implementation SayHello
-(void)sayHello{
NSLog(@"Hello");
}
-(void)dealloc{
NSLog(@"SayHello dead");
}
@end
顯然,這個類旨在給我一個函數來調用一個塊( sayHello
)並在NSLog
分配時生成一個NSLog
。
我像這樣運行我的測試:
SayHello *hello = [[SayHello alloc] init];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
double delayInSeconds = 30.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[hello sayHello];
});
});
30秒甚至給出了最懶惰的runloop時間來釋放“hello”對象(事實上,如果沒有保留它)。 但對於那些30秒,控制台是沉默的。 在30秒過期后,我立即得到“Hello”,然后是“SayHello dead”消息。
那么這是一個“陷阱”怎么樣? 嗯,很明顯,如果你沒有意識到Blocks / ARC正在這樣做,它最終可能會保留你認為應該消失的東西。 還有你的UITableViewCell
示例; 如果您的單元格顯示一次並通過網絡向圖像發送請求怎么辦?但是當塊正在等待圖像時,單元格會被重用? 現在有第二個塊參考該單元試圖設置其圖像。 好吧,現在你有一場比賽,失敗者將決定顯示什么圖像。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.