2012-02-01 5 views
9

पर यूआई अपडेट करें मेरे पास क्यू का उपयोग करके मुख्य धागे पर यूआई अपडेट करने से संबंधित एक प्रश्न है।dispatch_get_main_queue()

अच्छा, मान लीजिए कि हमारे पास UITableView है जो UIIabelView के साथ UILabel दिखाता है। UIImage के prepareCellfor में अतुल्यकालिक रूप से लोड किए गए हैं .. का उपयोग कर:

dispatch_async(t_queue, ^{ 
    //load image 
    //dispatch_async(dispatch_get_main_queue(),^{ 
    cell.imageView = image; 
    } 
}); 

लेकिन जब ब्लॉक छवि प्राप्त करते समय है उपयोगकर्ता एक कक्ष (या नेविगेशन दृश्य नियंत्रक पर वापस बटन) है कि सेल के लिए डी DetailViewController एक लोड (प्रेस या ऐप में वापस चला जाता है)।

मेरा प्रश्न है: क्या होता है जब ब्लॉक मुख्य छवि को अद्यतन करने के लिए मुख्य थ्रेड लॉन्च करता है? यह एक UIView कि खिड़की पर लोड नहीं है अद्यतन करने के लिए कोशिश कर रहा है या यहां तक ​​कि इसे अनलोड किया गया है सकते हैं ...

धन्यवाद

उत्तर

14

यह एक अच्छा सवाल है। और ARC का उपयोग करते समय उत्तर अनिवार्य रूप से है कि ब्लॉक स्वयं ऑब्जेक्ट को बरकरार रखता है, ताकि यह बाद में हो। यह उन सूक्ष्म स्मृति गॉटचास में से एक है। यदि UITableView जिस से यह सेल आता है, उसे आवंटित किया जाता है और इसकी सभी कोशिकाओं को रिलीज़ किया जाता है, तो इसे बनाए रखा जाएगा (हालांकि ऑफ-स्क्रीन) और cell.imageView = image; का कार्य पूरा हो जाएगा, फिर इसे जारी किया जाएगा।

मैं नियंत्रित प्रयोगों का एक बड़ा प्रशंसक हूं और इसका परीक्षण करने के लिए तैयार हूं, लेकिन UITableView में कई चलती हिस्से हैं (कोई इरादा नहीं है)। तो मैं एक बहुत ही सरल प्रयोग बनाया गया है, इस प्रकार एक साधारण NSObject उपवर्ग का उपयोग कर:

@implementation SayHello 
-(void)sayHello{ 
    NSLog(@"Hello"); 
} 
-(void)dealloc{ 
    NSLog(@"SayHello dead"); 
} 
@end 

जाहिर है इस वर्ग के लिए मुझे एक ब्लॉक (sayHello) में कॉल करने के लिए एक समारोह देना है और एक 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 समय "हैलो" वस्तु पुनःआवंटन (यदि, वास्तव में, यह नहीं रखा गया था) देता है। लेकिन उन 30 सेकंड के लिए कंसोल चुप है। 30 सेकंड की समयसीमा समाप्त होने के बाद मुझे तुरंत "हैलो" मिलता है जिसके बाद "SayHello मृत" संदेश मिलता है।

तो यह "गॉचा" कैसा है? खैर, जाहिर है अगर आपको एहसास नहीं होता कि ब्लॉक/एआरसी ऐसा कर रहे हैं, तो यह उन चीजों को ध्यान में रखकर समाप्त हो सकता है जिन्हें आपने सोचा था। लेकिन UITableViewCell के आपके उदाहरण के साथ भी; क्या होगा यदि आपका सेल एक बार प्रदर्शित होता है और किसी छवि के लिए नेटवर्क पर अनुरोध भेजता है, लेकिन जब ब्लॉक छवि के लिए प्रतीक्षा कर रहा है तो सेल का पुन: उपयोग किया जाता है? अब उस सेल के संदर्भ में एक दूसरा ब्लॉक है जो इसकी छवि सेट करने का प्रयास कर रहा है। खैर, अब आपके पास एक दौड़ है जिसमें हारने वाला यह तय करेगा कि कौन सी छवि प्रदर्शित होती है।

संबंधित मुद्दे