6

में एनएसटीएचड नींद का उपयोग करना कुछ कोड के साथ काम करना, मैं रन लूप में आ रहा हूं, जो मैं NSOperation एस के अंदर नया हूं।एनएसओपरेशन

NSOperation रों व्यस्त डाउनलोड डेटा कर रहे हैं - और जब वे व्यस्त हैं, वहाँ डाउनलोड पूर्ण होने की प्रतीक्षा करने के लिए NSRunLoop और धागा नींद के रूप में, कोड है।

विशेष रूप से इस कोड मेरे लिए ब्याज की है:

while (aCertainConditionIsTrue && [self isCancelled]==NO) { 
    if(![[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]){ 
     [NSThread sleepForTimeInterval:1.0]; 
    } 
} 

मैं रन छोरों के बारे में पढ़ा है, और runMode:beforeDate: एक इनपुट स्रोत या टाइमआउट के लिए इंतजार करेंगे। हालांकि मैं 100% नहीं हूं जो इनपुट सॉस के रूप में गिना जाता है।

इसके पहले निष्पादन पर यह हमेशा नहीं लौटाता है और sleepForTimeInterval: हिट करता है। क्या यह बुरा है?

किसी विशेष उपयोगिता वर्ग में, यह sleepForTimeInterval: बहुत कुछ मार रहा है - एक बार प्रत्येक थ्रेड के लिए - जो प्रदर्शन को काफी नुकसान पहुंचाता है।

इसके लिए कोई बेहतर समाधान, या सलाह?

उत्तर

2

सोते धागे को ताले लगाते हैं। शायद आप प्रदर्शन कोड का उपयोग करने के लिए अपना कोड बदल सकते हैं: withObject: afterDelay के बाद। इस तरह आपका धागा दौड़ना जारी रख सकता है।

... 
    done = NO; 
    [self checkDoneCondition:nil]; 
    ... 

- (void)checkDoneCondition:(id)object { 
    if (aCertainConditionIsTrue && [self isCancelled]==NO) { 
     if(...) { 
      [self performSelector:@selector(checkDoneCondition:) withObject:[con error] afterDelay:1.0]; 
     } else { 
      done = YES; 
     } 
    } 
} 
1

ऐसा लगता है कि आप एक समवर्ती NSOperation उपयोग करने के लिए की जरूरत है।

एक गैर समवर्ती ऑपरेशन है, जो तुल्यकालिक चलाता है, के विपरीत एक समवर्ती आपरेशन अतुल्यकालिक रूप से चलाता है: यहाँ एप्पल डॉक्स में प्रासंगिक हिस्सा है। दूसरे शब्दों में, जब आप समवर्ती ऑपरेशन की प्रारंभ विधि को कॉल करते हैं, तो वह कार्य संबंधित कार्य पूरा होने से पहले वापस लौटा सकता है। यह हो सकता है क्योंकि ऑपरेशन ऑब्जेक्ट ने कार्य निष्पादित करने के लिए एक नया धागा बनाया है या ऑपरेशन को एसिंक्रोनस फ़ंक्शन कहा जाता है। वास्तव में कोई फर्क नहीं पड़ता कि ऑपरेशन चल रहा है जब नियंत्रण कॉलर पर लौटाता है, केवल यह कि यह चल रहा है। (...) एक समवर्ती ऑपरेशन में, आपकी प्रारंभ विधि के लिए एक असीमित तरीके से ऑपरेशन शुरू करने के लिए ज़िम्मेदार है। चाहे आप धागे को फेंक दें या एसिंक्रोनस फ़ंक्शन को कॉल करें, आप इसे इस विधि से करते हैं। ऑपरेशन शुरू करने पर, आपकी प्रारंभ विधि को ऑपरेशन की निष्पादन स्थिति को अपडेट करना चाहिए जैसा कि विधि है। आप के लिए केवीओ नोटिफिकेशन भेजकर ऐसा करते हैं, मुख्य पथ का समर्थन करना, जो इच्छुक ग्राहकों को यह बताता है कि ऑपरेशन अब चल रहा है। आपकी isxtinging विधि को थ्रेड-सुरक्षित तरीके से स्थिति भी वापस करनी होगी।

(https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html से)

दूसरे शब्दों में, आप -start विधि अपने NSOperation उपवर्ग में ओवरराइड, और executing और finished संपत्ति के लिए इवर हो सकता है। यह विधि एक अलग धागे में डाउनलोड शुरू कर देगा। जब डाउनलोड शुरू होता है, तो आप executing ध्वज सेट करते हैं और केवीओ को ट्रिगर करते हैं।जब यह इस धागे में समाप्त हो जाता है, तो आप finished और executing के साथ ऐसा ही करते हैं। यह जटिल लगता है लेकिन यह वास्तव में काफी सरल है।

एक शानदार स्पष्टीकरण के साथ स्टैक ओवरफ़्लो पर यह प्रश्न भी देखें: Subclassing NSOperation to be concurrent and cancellable