2016-07-02 5 views
8

निम्नलिखित कोड स्निपेट पूरी तरह से काम करता है जब पूर्णता ब्लॉक के बाहर बुलाया जाता है, लेकिन जब मैं इसे ब्लॉक के अंदर सेट करता हूं तो टाइमर कभी नहीं निकाल दिया जाता है। मुझे समझ नहीं आता क्यों एक अंतर है:ब्लॉक के बाहर सेटअप करते समय 'निर्धारित टाइमर' ठीक से क्यों आग लगती है, लेकिन ब्लॉक के भीतर नहीं?

self.timer = Timer.scheduledTimer(timeInterval: 1, 
            target: self, 
            selector: #selector(self.foo), 
            userInfo: nil, 
            repeats: true) 

मैं जब ब्लॉक के बाहर शुरू में यह बुला स्वयं संदर्भों का उपयोग नहीं किया गया था, लेकिन फिर एक बार अंदर, यह आवश्यक था। हालांकि मैंने ब्लॉक के बाहर एक ही कोड का परीक्षण किया और यह अभी भी काम करता है।

ब्लॉक एक पूरा करने वाला हैडर जिसे HealthKit संबंधित जानकारी के लिए अनुमति मांगने के बाद बुलाया जाता है।

उत्तर

26

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

इसे ठीक करने के कि पूरा हैंडलर में, वापस मुख्य थ्रेड पर टाइमर के निर्माण के प्रेषण और यह ठीक काम करना चाहिए:

DispatchQueue.main.async { 
    self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true) 
} 

या एक प्रेषण स्रोत टाइमर (एक टाइमर है कि निर्धारित किया जा सकता का उपयोग एक पृष्ठभूमि कतार के लिए, और एक रन लूप की आवश्यकता नहीं है)।

var timer: DispatchSourceTimer! 

func startTimer() { 
    let queue = DispatchQueue(label: "com.domain.app.timer") 
    timer = DispatchSource.timer(queue: queue) 
    timer.setEventHandler { [weak self] in 
     // do something 
    } 
    timer.scheduleRepeating(deadline: .now(), interval: 1.0) 
    timer.resume() 
} 
+0

धन्यवाद बहुत समझ में आता है। मैंने उसके बारे में सोचा होता। धन्यवाद। – Kevin

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