2010-08-05 12 views
6

मैं वर्तमान में एक iPhone अनुप्रयोग पर काम कर रहा हूँ और मैं एक तीसरे पक्ष के अतुल्यकालिक व्यवहार है कि से एक पुस्तकालय है, लेकिन मैं अपने ही वर्ग के साथ रैप और यह तुल्यकालिक प्रदर्शित करने के लिए करना चाहते हैं।यह कैसे तुल्यकालिक बनाने के लिए एक अतुल्यकालिक वर्ग रैप करने के लिए? NSRunLoop का प्रयोग करें?

इस पुस्तकालय में केंद्रीय वर्ग, चलो यह कनेक्शन वर्ग कॉल, कई कार्य है कि उनके अंतिम परिणाम का समाधान जब एक प्रतिनिधि वर्ग का एक उदाहरण पर पद्धतियों को बुलाया जाता है। जो मैं करने की कोशिश कर रहा हूं वह इस वर्ग को लपेटता है और प्रतिनिधि करता है ताकि यह असीमित के बजाय सिंक्रोनस हो। अगर मैं जावा में ऐसा कर रहा था तो मैं फ्यूचरटास्क या काउंटडाउनलैच का उपयोग करूंगा या बस() में शामिल होगा। लेकिन मुझे यकीन नहीं है कि उद्देश्य सी

में मैंने ऐसा करने का सबसे अच्छा तरीका सुनिश्चित किया है, मैंने उपरोक्त उल्लिखित प्रतिनिधि प्रोटोकॉल के अनुरूप एनएसटीएचएचटी एक्सटेन्स्टियन, एनएफसीटीएचडी तैयार करके शुरू किया था। विचार यह है कि मैं init हैं और NFCThread,, कनेक्शन के setDelegate विधि के लिए NFCThread उदाहरण पारित धागा शुरू हुई और फिर कनेक्शन पर एक अतुल्यकालिक विधि कहते हैं। मेरी उम्मीद यह है कि एनएफसीएचएचएड उदाहरण पर तीन प्रतिनिधि तरीकों में से एक को आखिरकार थ्रेड से बाहर निकलने का कारण बताया जाएगा।

एक में शामिल होने के मैं निम्नलिखित किया अनुकरण करने के लिए। मैं NFCThread करने के लिए एक NSConditionalLock कहा:

NFCThread *t = [[NFCThread alloc] init]; 
[connection setDelegate:t]; 
[t start]; 

[connection openSession]; 
// Process errors, etc... 

[t.joinLock lockWhenCondition:YES]; 
[t.joinLock unlock]; 
[t release]; 
[connection setDelegate:nil]; 

प्रतिनिधि के लिए प्रोटोकॉल तीन विधियों है:

joinLock = [[NSConditionLock alloc] initWithCondition:NO]; 

कनेक्शन करने के लिए कॉल के आसपास कोड कुछ इस तरह लग रहा है।

- (void)didReceiveMessage:(CommandType)cmdType 
        data:(NSString *)responseData 
       length:(NSInteger)length { 
    NSLog(@"didReceiveMessage"); 
    // Do something with data and cmdType... 
    [joinLock lock]; 
    [joinLock unlockWithCondition:YES]; 
    callBackInvoked = YES; 
} 

मैं NFCThread के मुख्य विधि अतिभारित इतना है कि यह सिर्फ लगातार लूप: NFCThread में मैं इस तरह प्रत्येक विधि कुछ को लागू किया। कुछ इस तरह:

while (!callBackInvoked) { ; } 

मैंने पाया कि यह वास्तव में एक अच्छा विचार के बाद से यह cpu उपयोग छत के माध्यम से जाना करने के लिए कारण नहीं है। तो बजाय मैं कुछ उदाहरण मैं इस साइट पर पाया से एक रन पाश उपयोग करने की कोशिश:

NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; 

while (!callBackInvoked) { 
    [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 
} 

मेरी कार्यान्वयन के दोनों में मुख्य थ्रेड हमेशा अवरुद्ध है और ऐसा लगता है कि प्रतिनिधि के तरीकों में से कोई भी कभी कहा जाता है। हालांकि, मुझे पता है कि पुस्तकालय ठीक से काम कर रहा है और प्रतिनिधि विधियों को कॉल सामान्य रूप से बुलाया जाता है।

मुझे लगता है कि मुझे यहां कुछ स्पष्ट याद आ रहा है। किसी भी मदद की बहुत सराहना की।

रिच

उत्तर

0

ठीक है, तो यहां कुछ अलग-अलग मुद्दे हैं, मैं सोचने की कोशिश कर रहा हूं कि कहां से शुरू करना है।

लेकिन बस हम समझते हैं कि आप क्या हासिल करने की कोशिश कर रहे हैं, जब आप कहते हैं कि आप कॉल को "सिंक्रोनस" करने के लिए चाहते हैं, तो क्या आपका मतलब है कि आप कॉल को अवरुद्ध करना चाहते हैं? क्या आप इस कॉल को मुख्य धागे से बना रहे हैं?यदि ऐसा है, तो ऐसा लगता है कि आप डिजाइन द्वारा मुख्य धागे को अवरुद्ध कर रहे हैं।

ध्यान रखें तीसरे पक्ष के पुस्तकालय शायद मुख्य रन पाश पर घटनाओं का समय निर्धारण किया गया है। आप अपना खुद का रन लूप बना सकते हैं और इसे किसी अन्य थ्रेड में चला सकते हैं, लेकिन क्या आपने अन्य लाइब्रेरी को अपने कार्यक्रमों के लिए उस रन लूप का उपयोग करने के लिए कहा है? (उदाहरण के लिए, यह एएसआईएनसी नेटवर्क अनुरोध कर सकता है जो आपके द्वारा अवरोधित किए गए मुख्य रन लूप पर निर्धारित हैं)

मैं पुनर्विचार करूँगा कि आप थोड़ा क्या कर रहे हैं, लेकिन पहले हमें यह जानना होगा कि आपका इरादा है या नहीं उस धागे को अवरुद्ध करने के लिए जिससे आप यह कॉल कर रहे हैं। इसके अलावा, क्या आपको iPhoneOS 3.x का समर्थन करने की आवश्यकता है?

+0

धन्यवाद, फिरोज़। हां, हमारा इरादा ब्लॉक करने के लिए हमारे सिंक्रोनस कॉल होना है। यह तीसरी पार्टी लाइब्रेरी वास्तव में एक एसडी कार्ड के साथ इंटरफेसिंग कर रही है, लेकिन मुझे लगता है कि यह सिर्फ एक विवरण है। साथ ही, करीब निरीक्षण के बाद, मैंने अभी निर्धारित किया है कि प्रतिनिधि पद्धतियों पर कॉल मुख्य धागे पर भी होती है। क्या यह इस पूरे चर्चा को प्रस्तुत कर सकता है? – richever

+1

ठीक है, मुझे यकीन नहीं है कि यह मंथन है। बात यह है कि यदि आप कॉल को अवरुद्ध करना चाहते हैं, और आप मुख्य धागे को अवरुद्ध करते हैं, तो यह अन्य लाइब्रेरी अपना काम पूरा नहीं कर सकती है। तो एक ही जवाब एक अलग धागे से तुल्यकालिक कॉल, जो ब्लॉक कर देगा * कि * धागा बनाने के लिए, लेकिन अभी भी मुख्य थ्रेड सामान्य रूप से कार्य करने के लिए जारी करने की अनुमति होगी। बेशक यदि आप इस तरह के कई धागे बनाने और अवरुद्ध करना चाहते हैं, तो यह बहुत अच्छा नहीं है। किसी भी मामले में, मैं के बारे में सोचना होगा * क्यों * यदि आप इस सिंक चाहते हैं और हो सकता है एक गैर अवरुद्ध रास्ता एक ही बात करने के लिए के बारे में सोच रहा अवरुद्ध विधि फोन कर रहा हूँ –

+0

(आप यहाँ करने के लिए कोशिश कर रहे हैं के और अधिक जानने की आवश्यकता है) जैसा कि आपने फिरोज़ का सुझाव दिया था, और यह काम करने लगता है। की तरह। मेरा अनुसरण प्रश्न देखें: http://stackoverflow.com/questions/3444557/error-at-nsrunloop-after-returning-from-thread-method-with-nsautoreleasepool – richever

4

आप एक सेमाफोर है, जो जब तक आपके अतुल्यकालिक कॉलबैक सेमाफोर का संकेत है और यह जारी रखने के लिए अनुमति देता है अपनी प्राथमिक codepath ब्लॉक करने के लिए अनुमति देगा चाहते हैं।

Semaphores ग्रांड सेंट्रल डिस्पैच के माध्यम से आईओएस 4 में उपलब्ध हैं।

ऐसा प्रतीत होता है कि सेफफोर्स का व्यवहार एनएससीओंडिशन के साथ आईओएस 3 में लागू किया जा सकता है।

+0

धन्यवाद सीमस, लेकिन दुर्भाग्यवश लाइब्रेरी जो मैं इस प्रश्न में उल्लेख करता हूं उसे 3.x तक संकलित किया गया है, इसलिए, हम जीसीडी का उपयोग नहीं कर सकते हैं। कोई अन्य सुझाव? – richever

2

मैं बस कुछ इसी तरह से लागू किया। संदर्भ था: - पृष्ठभूमि थ्रेड में ZipArchive को कई कॉल लपेटें - प्रत्येक कॉल को अनजिप करने के लिए, एक अलग प्रगति मीटर प्रदर्शित करें (फ़ाइल के नाम के साथ असीमित कताई चक्र) - सभी सफाई कार्य करें अभिलेखागार

का विस्तार किया गया है

बाहर कर देता है NSConditionLock यह सरल बनाता है, और इस प्रकार कोड काम करता है:

NSConditionLock* lock = alloc/init 
for(int idx = 0; idx < [list count]; idx++) { 
    NSString* fileName = ["getIdx's element in list"] 
    [cond lockWhenCondition:idx]; // 

    ... prepare things before forking 

    [cond unlockWithCondition:-1]; 
    [Notification forkBlock:^(void){ 
    [cond lockWhenCondition:-1]; 

    NSAutoreleasePool *pool = [alloc/init]; 
    [ZipArchive unzipFile:fileName]; 
    [pool release]; 
    [cond unlockWithCondition:idx+1]; 
    }]; 
} 

[cond lockWhenCondition:[list count]; 
// all the tasks are now completed 

ब्लॉकों में से प्रत्येक एक पृष्ठभूमि सूत्र में निर्धारित हैं। अधिसूचना वर्ग कताई चक्र के साथ UIView को एनिमेट करने और ब्लॉक को दूसरे धागे में लपेटने का ख्याल रखता है। लॉक/अनलॉक को उसी धागे से बुलाया जाना चाहिए, इसलिए स्थिति पिंग-पोंग से और पृष्ठभूमि धागे के बीच सक्षम होती है (पृष्ठभूमि के लिए -1, अग्रभूमि के लिए 1,2,3..एन)।

0

क्या आप क्या करना चाहते NSCondition उपयोग करने के लिए वर्तमान धागे पर प्रतीक्षा करें, और दूसरे धागे पर संकेत पहले एक जारी रखने के लिए जाने के लिए है।

- (void) firstThread 
{ 
    workIsDone = NO; 
    //Start second thread here 
    [condition lock]; 
    while (!workIsDone) { 
     [condition wait]; 
    } 
    [condition unlock]; 

    // Keep going 
} 

- (void) secondThread 
{ 
    [condition lock]; 

    //Do some work. 
    workIsDone = YES; 
    [condition signal]; 
    [condition unlock]; 
} 
संबंधित मुद्दे

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