मेरे पास एक NSRunLoop ऑब्जेक्ट है, जिसमें मैं टाइमर और स्ट्रीम संलग्न करता हूं। यह बहुत अच्छा काम करता है। इसे रोकना एक और कहानी है।CFRunLoopRun() बनाम [NSRunLoop रन]
मैं [runLoop run]
का उपयोग कर लूप चलाता हूं।
यदि मैं CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop])
का उपयोग करके लूप को रोकने का प्रयास करता हूं, तो लूप रुक जाएगा नहीं। अगर मैं इसके बजाय CRunLoopRun()
का उपयोग कर लूप शुरू करता हूं, तो यह काम करता है। मैंने यह भी सुनिश्चित किया है कि कॉल सही धागे पर बनाया गया है (जो मेरा कस्टम रन लूप चला रहा है)। मैंने pthread_self()
के साथ इसे डीबग किया है।
मुझे एक मेलिंग सूची संग्रह मिला, जहां एक डेवलपर ने कहा "CRunLoopStop()
का उपयोग करके परेशान न करें अगर आपने NSRunLoop
की रन विधि का उपयोग करके लूप शुरू किया है"। मैं समझ सकता हूं कि यह तरीका क्यों है - आप आम तौर पर कार्यों के एक ही सेट से प्रारंभकर्ताओं और फाइनलरों को जोड़ते हैं।
"सीएफ का सहारा लेने" के बिना आप NSRunLoop
को कैसे रोकते हैं? मुझे विधि NSRunLoop
पर नहीं दिखाई दे रही है। डॉक्स का कहना है कि आप तीन तरीकों से एक रन पाश बंद कर सकते हैं:
- कॉन्फ़िगर एक टाइमआउट मान के साथ चलाने के लिए
- बताएँ रन पाश
CFRunLoopStop()
- का उपयोग करके सभी इनपुट सूत्रों निकालें को रोकने के लिए रन पाश, लेकिन यह एक अविश्वसनीय रन पाश को रोकने के लिए है क्योंकि आप कभी पता नहीं क्या कर सकते हैं के पीछे अपनी पीठ
खैर रन लूप में क्या अटक रास्ता है, मैं पहले से ही 2 की कोशिश की और वहाँ यह करने के लिए लग रहा है एक "बदसूरत", क्योंकि आप सीएफ में खोदना है 3. सवाल से बाहर है - मैं गैर निर्धारक कोड कल्पना नहीं करता हूं।
यह हमें 1 के साथ छोड़ देता है। यदि मैं दस्तावेज़ों को सही ढंग से समझता हूं, तो आप पहले से मौजूद रन लूप में "टाइम" नहीं जोड़ सकते हैं। आप केवल टाइमआउट के साथ नए रन लूप चला सकते हैं। यदि मैं एक नया रन लूप चलाता हूं, तो यह मेरी समस्या का समाधान नहीं करेगा, क्योंकि यह केवल एक नेस्टेड रन लूप बनाएगा। मैं अभी भी पुराने में वापस आऊंगा, वैसे ही मैं रुकना चाहता था ... सही? मैंने शायद इसे गलत समझा होगा। साथ ही, मैं लूप को टाइमआउट मान के साथ नहीं चलाना चाहता हूं। यदि मैं करता हूं, तो मुझे सीपीयू चक्र (कम टाइमआउट मान) और प्रतिक्रियाशीलता (उच्च टाइमआउट मान) जलने के बीच एक व्यापार करना होगा।
यह अभी सेटअप मेरे पास है (छद्म कोड-ish):
Communicator.h
@interface Communicator : NSObject {
NSThread* commThread;
}
-(void) start;
-(void) stop;
@end
Communicator.m
@interface Communicator (private)
-(void) threadLoop:(id) argument;
-(void) stopThread;
@end
@implementation Communicator
-(void) start {
thread = [[NSThread alloc] initWithTarget:self
selector:@selector(threadLoop:)
object:nil];
[thread start];
}
-(void) stop {
[self performSelector:@selector(stopThread)
onThread:thread
withObject:self
waitUntilDone:NO];
// Code ommitted for waiting for the thread to exit...
[thread release];
thread = nil;
}
@end
@implementation Communicator (private)
-(void) stopThread {
CRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]);
}
-(void) threadLoop:(id) argument {
// Code ommitted for setting up auto release pool
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
// Code omitted for adding input sources to the run loop
CFRunLoopRun();
// [runLoop run]; <- not stoppable with
// Code omitted for draining auto release pools
// Code omitted for signalling that the thread has exited
}
@endif
मैं क्या कर रहा हूँ करने के लिए? क्या यह सीएफ के साथ गड़बड़ करने के लिए आम/अच्छा पैटर्न है? मैं फाउंडेशन को काफी अच्छी तरह से नहीं जानता। सीएफ परत में हस्तक्षेप संभवतः खतरनाक है (स्मृति भ्रष्टाचार, असंगतता, स्मृति रिसाव के संबंध में)? क्या मैं हासिल करने की कोशिश कर रहा हूं, हासिल करने के लिए एक बेहतर पैटर्न है?
आह, चालाक! मैंने नहीं देखा कि 'runMode' केवल एक बार भाग गया। क्या रन लूप को बार-बार शुरू करके कोई महत्वपूर्ण प्रदर्शन जुर्माना लगाया गया है? –
नहीं, ऐसा नहीं है: इस प्रकार '- [NSRunLoop रन] 'और' - [NSRunLoop runUntilDate:]' कार्य है। –
थ्रेड नहीं रुक जाएगा यदि आप अभी सेट करें loopIs को YES पर रोक दिया गया है। आपको इसे YES पर सेट करने और उस रनलोप के धागे पर एक क्रिया करने की आवश्यकता है, अन्यथा [runLoop runMode: NSDefaultRunLoopMode पहले दिनांक: दिनांक] बाहर नहीं निकलता है। यह मुझे समझने के लिए उम्र ले गया। – Pada