5

ग्रांड सेंट्रल डिस्पैच बहुत अच्छा है और कोड की मात्रा कम कर देता है लेकिन मैं पृष्ठभूमि थ्रेड पर कुछ क्यों नहीं चला सकता?तुलना जीसीडी बनाम प्रदर्शन चयनकर्ताबैकग्राउंड: dispatch_async पृष्ठभूमि में नहीं

- (IBAction)performSel { 
    [self performSelectorInBackground:@selector(doStuff) withObject:nil]; 
    [NSThread sleepForTimeInterval:3]; 
    [[self.view.subviews lastObject] removeFromSuperview]; 
} 

- (IBAction)gcd { 
    dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) { 
    //dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) { 
    //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
    //dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
    //dispatch_async(dispatch_get_main_queue(), ^(void) { 
    //dispatch_sync(dispatch_get_main_queue(), ^(void) { 
     [self doStuff]; // only for readability, will move the code on success 
    }); 
    [NSThread sleepForTimeInterval:3]; 
    [[self.view.subviews lastObject] removeFromSuperview]; 
} 

- (void)doStuff { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 

    UIView *abortingView = [[UIView alloc]initWithFrame: self.view.bounds]; 
    abortingView.backgroundColor = [UIColor whiteColor]; 
    abortingView.alpha = 0.7; 
    [self.view insertSubview:abortingView atIndex:10]; 
    [abortingView release]; 

    [pool drain]; 
} 

[NSThread sleepForTimeInterval:3]; एक डिफ़ॉल्ट यूआई कार्यक्षमता अनुकरण करने के लिए है:
मैं दिखाने के लिए मैं क्या मतलब है (टिप्पणी की कोई भी काम न) एक नमूना आवेदन कर दिया है। उदाहरण के लिए यदि कोई एक नेविगेशन व्यू से दूसरे में स्विच कर रहा है।
बस नए दृश्य आधारित एप्लिकेशन में कोड कॉपी करें, दो बटन बनाएं और उन्हें कनेक्ट करें।

+0

आईबीएक्शन-विधियों के जवाब में लंबे समय से चलने वाले कार्यों को सोना या करना हमेशा एक बुरा विचार है – Felix

उत्तर

23

UIKit कक्षाओं का उपयोग केवल किसी एप्लिकेशन के मुख्य थ्रेड से ही किया जाना चाहिए। (आईओएस 4 से, ग्राफिक्स संदर्भ में ड्राइंग थ्रेड-सुरक्षित है।) आप पृष्ठभूमि थ्रेड में UIKit सामान का उपयोग नहीं कर सकते हैं।

इस प्रकार, आप केवल इस स्थिति में dispatch_async (dispatch_get_main_queue(), ब्लॉक) का उपयोग कर सकते हैं।

dispatch_async(dispatch_get_main_queue(), ^(void) { 

यह मुख्य धागे के रनलूप में मुख्य धागे पर ब्लॉक को आमंत्रित करेगा।

dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) { 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 

यह पृष्ठभूमि थ्रेड में ब्लॉक को आमंत्रित करेगा। आप इसका उपयोग नहीं कर सकते क्योंकि आप ब्लॉक में UIKit का उपयोग करना चाहते हैं। और सावधान dispatch_async (dispatch_queue_create ( हो, यह स्मृति रिसाव के कारण हो सकता है, तो आप धारावाहिक कतार कि dispatch_queue_create द्वारा बनाई गई है जारी करने के लिए है।

dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) { 
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 

dispatch_sync जब तक ब्लॉक किया जाता है इंतजार कर रहा है।

dispatch_sync(dispatch_get_main_queue(), ^(void) { 

यह डेडलॉक का कारण बनता है।

+1

आपको 'dispatch_queue_create (" myGCDqueue ", NULL) का उपयोग नहीं करना चाहिए क्योंकि तुम लीक हो जाओगे। आपको किसी बिंदु पर बनाई गई कतार को रिलीज़ करना होगा - आम तौर पर उस पर कुछ ब्लॉक भेजने के बाद – shw

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

  • कोई संबंधित समस्या नहीं^_^