2010-01-03 11 views
22

मैं बस अपने ऐप के साथ समाप्त हो गया हूं और बीटा परीक्षण स्टॉपवॉच भाग में एक बग मिला है ... स्टॉपवॉच गिनती करने के लिए एक nstimer का उपयोग करता है और अंतराल भंडारण के लिए एक टेबल है, लेकिन जब गोद की मेज स्क्रॉल होती है तो घड़ी बंद हो जाती है या रुक जाती है और खो समय के लिए तैयार नहीं होती है।रनस्टॉप अवरुद्ध होने पर NSTimer फायरिंग नहीं है

इस रोकने का उपयोग करके हटा दिया गया था:

startingTime = [[NSDate date] timeIntervalSince1970]; 

बीता हुआ समय की गणना करने के।

लेकिन मैं अभी भी प्रत्येक 0.1 सेकंड को ट्रिगर करने के लिए एनएसटीमर का उपयोग कर रहा हूं और इसका मतलब है कि स्क्रॉलिंग अभी भी टाइमर को स्टाइल करती है, भले ही विलुप्त समय अंत में सही ढंग से अपडेट किया जाएगा ... और इसे ऐप्पल स्टॉपवॉच से तुलना करना मुझे आश्चर्य है कि क्या स्टॉपवॉच के पास समय सीमा के लिए सिर्फ एक अलग धागा है। क्या किसी को पता है कि यह कैसे किया जाता है?

अब

, समय के बाद से युग एक अर्थ में अच्छी तरह से काम कर रहा है का उपयोग करते हुए, लेकिन यह शुरू रोक, & स्टॉपवॉच

जब देखे जाने की समयावधि संग्रहीत किया जाता है बंद कर दिया और गणना करने के लिए प्रयोग किया जाता है को पुन: प्रारंभ की बात पेचीदा जब घड़ी को फिर से शुरू किया जाता है, तो ऑफसेट होता है, लेकिन कुछ विलंबता प्रतीत होती है और घड़ी को फिर से शुरू होने पर समय स्पष्ट रूप से आगे बढ़ता है।

मूल कारण या समाधान की ओर कोई विचार बहुत सराहना की जाएगी।

उत्तर

22

यदि ईवेंट लूप नहीं चल रहा है, तो ईवेंट लूप फिर से चलाए जाने तक कोई टाइमर आग नहीं लगेगा। यहां तक ​​कि यदि ईवेंट लूप ब्लॉक नहीं है, तो टाइमर को इसके कॉन्फ़िगर किए गए अंतराल पर आग लगाने की गारंटी नहीं है। यदि आपका समय पूरी तरह टाइमर फायरिंग पर आधारित था, तो समय के साथ त्रुटि की मात्रा बढ़ेगी।

आपको टाइमर की गोलीबारी से अलग अवधि का ट्रैक रखने की आवश्यकता है। प्रत्येक बार एक टाइमर आग लगती है, अपनी अवधि को फिर से समझें और फिर से चलाएं।

  • हड़पने समय प्रारंभ पर (या तो एक NSDate उदाहरण के रूप में या एक NSTimeInterval मूल्य के रूप में)

  • :

    एक शुरुआत/रोकें/पुनः आरंभ करने के लिए/सेटअप के प्रकार के बंद करो, तुम आम तौर पर करना चाहते हैं

    रोकें या रोकें, रोकें/रोकें पर समय पकड़ो। इस समय से शुरू करने का समय घटाएँ और आप अंतराल की अवधि

  • पुनः आरंभ करने पर

    है, पुनः आरंभ पर समय हड़पने लेकिन यह भी पहले से ही बीत अवधि

  • ठहराव पर

    के आसपास रखना/बंद करो, पर समय हड़पने रोकें/बंद करो और पहले से ही बीत अवधि

जोड़ने सामान्य तौर पर, NSTimeInterval मूल्यों के साथ यह सब करने के - जो सिर्फ डबल्स - सबसे आसान है। हालांकि, यदि घटनाओं के समय में वास्तविक क्षण का ट्रैक रखने की आवश्यकता है, तो इसके बजाय NSDate उदाहरणों का उपयोग करें।

46

बीबीएम का जवाब आपके आवेदन को डिजाइन करने का एक बेहतर तरीका प्रदान करता है, लेकिन यदि आप अपना टाइमर आग लगाना चाहते हैं कि उपयोगकर्ता यूआई में हेरफेर कर रहा है या नहीं, तो आपको इसे रनलोप के ट्रैकिंग मोड में जोड़ना होगा।

मान लें कि आप आईफोन के लिए विकास कर रहे हैं, वह मोड UITrackingRunLoopMode है। यदि आप मैक के लिए विकास कर रहे हैं तो इसी तरह नामित NSEventTrackingRunLoopMode है।

NSRunLoop *runloop = [NSRunLoop currentRunLoop]; 
NSTimer *timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(myTimerAction:) userInfo:nil repeats:YES]; 
[runloop addTimer:timer forMode:NSRunLoopCommonModes]; 
[runloop addTimer:timer forMode:UITrackingRunLoopMode]; 
+1

जो अभी भी समग्र समय की सटीकता की गारंटी नहीं देगा। टाइमर को उनके कॉन्फ़िगर किए गए अंतराल पर आग लगाने की गारंटी नहीं है। इससे भी बदतर, यदि प्रत्येक टाइमर फायरिंग समग्र अंतराल में जोड़ती है, तो प्रत्येक टाइमर फायरिंग के साथ त्रुटि की मात्रा में वृद्धि होगी! – bbum

+0

मुझे यह तर्क देने का इरादा नहीं था कि नियंत्रण ट्रैकिंग के दौरान टाइमर आग लगने के अलावा वे कुछ भी गारंटी देंगे। गोद में तारीख को संग्रहीत करना और उस समय का उपयोग करने के लिए उस समय का सटीक (और सरल आईएमओ) है जैसा आपने अपने उत्तर में कहा था। –

+0

+1 मेरे लिए काम किया। बीबीएम के जवाब ने मुझे कोई समझ नहीं दी। – bentford

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