2011-08-14 24 views
110

मेरे आईओएस डिवाइस में मेरे पास एक छोटा sqlitedb है। जब कोई उपयोगकर्ता बटन दबाता है, तो मैं डेटा को SQLite & से उपयोगकर्ता को दिखाता हूं।आईओएस पृष्ठभूमि थ्रेड शुरू करें

यह fetching भाग मैं इसे पृष्ठभूमि धागे में करना चाहता हूं (UI मुख्य थ्रेड को अवरुद्ध नहीं करने के लिए)। मैं तो इस तरह करते हैं - प्रसंस्करण का एक छोटा सा

[self performSelectorInBackground:@selector(getResultSetFromDB:) withObject:docids];

प्राप्त करने में कठिनाई & के बाद, मैं यूआई अपडेट करना होगा। लेकिन चूंकि (एक अच्छी प्रैक्टिस के रूप में) हमें पृष्ठभूमि धागे से यूआई अपडेट नहीं करना चाहिए। मैं तो जैसे mainthread पर एक selector कहते हैं -

[self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];

लेकिन मेरे अनुप्रयोग पहले चरण में दुर्घटनाओं। यानी पृष्ठभूमि धागा शुरू करना। क्या यह आईओएस में पृष्ठभूमि धागे शुरू करने का कोई तरीका नहीं है?

अद्यतन 1:[self performSelectorInBackground.... के बाद मैं इस स्टैकट्रेस, कोई जानकारी क्या इतना कभी मिलता है -

enter image description here

अद्यतन 2: मैं भी कोशिश की, जैसे एक पृष्ठभूमि धागा शुरू कर इतना - [NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids]; लेकिन अभी भी मुझे एक ही स्टैकट्रैक मिलता है।

बस इतना है कि मैं स्पष्ट है, जब मैं मुख्य थ्रेड सब कुछ पर इस कार्रवाई को चिकनी ...

अद्यतन 3 इस विधि मैं पृष्ठभूमि

- (void)getResultSetFromDB:(NSMutableArray *)toProceessDocids 
{ 
    SpotMain *mirror = [[SpotMain alloc] init]; 
    NSMutableArray *filteredDocids = toProceessDocids; 

    if(![gMediaBucket isEqualToString:@""]) 
     filteredDocids = [mirror FetchDocIdsForMediaBucketWithDocID:filteredDocids mBucket:gMediaBucket numRes:-1]; 
    if(![gMediaType isEqualToString:@""]) 
     filteredDocids = [mirror FetchDocIdsForMediaType:filteredDocids mediaType:gMediaType numRes:-1]; 
    if(![gPlatform isEqualToString:@""]) 
     filteredDocids = [mirror FetchDocIdsForPlatformID:filteredDocids platformId:@"1" numRes:-1]; 

    self.resultSet = [mirror FetchObjectFromDocid:filteredDocids]; 
    [filteredDocids release]; 
    [mirror release]; 

    [self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO]; 
    return; 
} 
+0

क्या त्रुटि/क्रैश लॉग आप मिलता है में एक बार देख ले सकते हैं: एक ठेठ कार्यप्रवाह कुछ इस तरह हो सकता है? – jtbandes

+0

कृपया मेरे अपडेट देखें ... –

+0

क्या आप पृष्ठभूमि में जिस विधि को बुला रहे हैं उसे दिखा सकते हैं? और सुनिश्चित करें कि ऑब्जेक्ट 'docids' को बनाए रखा गया है। – Rog

उत्तर

264

आप performSelectorInBackground:withObject: का उपयोग करते हैं एक नया धागा अंडे देने के लिए है, तो प्रदर्शन किया चयनकर्ता नया थ्रेड के autorelease पूल, चलाने के पाश और अन्य विन्यास विवरण की स्थापना के लिए जिम्मेदार है - एप्पल के थ्रेडिंग प्रोग्रामिंग गाइड में "Using NSObject to Spawn a Thread" देखते हैं।

आप शायद बेहतर होगा हालांकि, Grand Central Dispatch का उपयोग कर:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [self getResultSetFromDB:docids]; 
}); 

GCD एक नई तकनीक है, और भूमि के ऊपर स्मृति के मामले और कोड की लाइनों में अधिक सक्षम है।


Chris Nolet करने के लिए एक टोपी टिप, जो एक परिवर्तन यह है कि इसके बाद के संस्करण कोड सरल बना देता है और एप्पल के नवीनतम GCD कोड उदाहरण के साथ बने रहते सुझाव के साथ अपडेट किया गया।

+0

ठंडा! यह नहीं पता था। क्या यह '[NSThread detachNewThreadSelector: @selector .... 'पर भी लागू होता है? –

+0

हां। ऐप्पल डॉक्स के अनुसार, 'performSelectorInBackground: withObject:' "को कॉल करना, जैसा कि आपने वर्तमान ऑब्जेक्ट, चयनकर्ता, और पैरामीटर ऑब्जेक्ट के साथ पैरामीटर के रूप में 'detachNewThreadSelector: toTarget: withObject:' विधि 'nSThread'' कहा है।" –

+0

क्या इस मामले में '(हस्ताक्षर किए गए लंबे) न्यूल और' 0' के बीच कोई अंतर है? – Sti

4

से चलाने के लिए कोशिश कर रहा हूँ है चलाता है कौन सा ऑब्जेक्ट जारी किया जा रहा है और फिर एक्सेस किया गया है यह जानने के लिए NSZombieEnabled सक्षम करें। फिर जांचें कि getResultSetFromDB: के साथ कुछ भी करने के लिए है या नहीं। यह भी जांचें कि docids में कुछ भी है और यदि इसे बरकरार रखा जा रहा है।

इस तरह आप सुनिश्चित कर सकते हैं कि कुछ भी गलत नहीं है।

+0

कृपया उस पंक्ति की प्रतिलिपि बनाएं जो आपने मुख्य थ्रेड पर आसानी से चलाया है। –

+0

मैं इसे मुख्य धागे से उपयोग करता हूं और कम से कम यह अचानक क्रैश होने की बजाय उस विधि को हिट करता है - '[self getResultSetFromDB: docids]; ' –

+0

क्या मैंने आपको जो बताया है उसे सक्षम किया है? –

2

आईओएस के साथ आने वाली डिफ़ॉल्ट स्क्लाइट लाइब्रेरी को SQLITE_THREADSAFE मैक्रो का उपयोग करके संकलित नहीं किया गया है। यह एक कारण हो सकता है कि आपका कोड क्रैश क्यों होता है।

2

स्विफ्ट 2.x जवाब:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
     self.getResultSetFromDB(docids) 
    } 
4

खैर यह बहुत GCD साथ वास्तव में आसान है।

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul); 
    dispatch_async(queue, ^{ 
     // Perform async operation 
     // Call your method/function here 
     // Example: 
     // NSString *result = [anObject calculateSomething]; 
       dispatch_sync(dispatch_get_main_queue(), ^{ 
        // Update UI 
        // Example: 
        // self.myLabel.text = result; 
       }); 
    }); 

GCD अधिक जानकारी के लिए आप Apple's documentation here

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