मैं 1 सेकंड के लिए एक विधि कॉल में देरी कैसे कर सकता हूं?


164

क्या 1 सेकंड के लिए विधि कॉल में एक आसान तरीका देरी है?

मेरे पास एक UIImageViewस्पर्श घटना पर प्रतिक्रिया है। जब स्पर्श का पता लगाया जाता है, तो ऐप में कुछ एनिमेशन होते हैं। एक सेकंड के बाद, मैं दूसरी विधि को कॉल करना चाहता हूं। इस मामले में, मैं animationDidStopचयनकर्ता का उपयोग नहीं कर सकता ।


ऐसा करने के लिए निश्चित रूप से कई तरीके हैं, उनमें से एक बस नींद का उपयोग करना हो सकता है () मिलिसेकंड की एक संख्या के लिए कार्यक्रम / थ्रेड को निलंबित करने के लिए, हालांकि मुझे लगता है कि आप हमें यह बताना चाहते हैं कि आप वास्तव में क्या हासिल करना चाहते हैं। वह कर रहा? मेरा मतलब है, आपकी वास्तविक समस्या क्या है? एक विधि कॉल में देरी करने का विचार एक 'समाधान' की तरह लगता है, एक जो ईमानदार होने के लिए बहुत अच्छा नहीं लगता है। इसलिए, हमें अपने परिदृश्य के बारे में अधिक जानकारी दें।
कोई भी

जवाबों:


254
performSelector:withObject:afterDelay:

दस्तावेज़ संदर्भ


7
यह सही जवाब है। कृपया देखें developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/... :
हानि पहुँचाता

क्या विधि के रिटर्न वैल्यू के साथ कुछ करने का कोई तरीका है जिसे कहा जाता है? या क्या मुझे पैरामीटर को संशोधित करने के लिए इसे सेट करने की आवश्यकता है अगर मैं कुछ जानकारी वापस प्राप्त करना चाहता हूं?
गॉर्डन गुस्ताफ़सन

यदि कोई व्यक्ति निर्धारित कॉल को रद्द करने के लिए इच्छुक है: [NSObject रद्द करेंप्रेपप्रियरपरफॉर्मेंसविशेषज्ञता: अपनेTarget चयनकर्ता: aSelector ऑब्जेक्ट: aArgument];
हमें

192

तुम भी एक ब्लॉक का उपयोग कर सकते हैं

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [object method]; 
});

अधिकांश समय आप dispatch_get_main_queue का उपयोग करना चाहेंगे, हालाँकि यदि विधि में कोई UI नहीं है तो आप एक वैश्विक कतार का उपयोग कर सकते हैं ।

संपादित करें:

स्विफ्ट 3 संस्करण:

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    object.method()
}

समान रूप से, DispatchQueue.global().asyncAfter(...एक अच्छा विकल्प भी हो सकता है।


सीधे C और ObjC को मिलाते समय PerformSelector की तुलना में आसान होने के लिए यह समाधान मिला
पॉल स्लोकम

1
दुर्भाग्य से dispatch_get_current_queue iOS6 के बाद से हटा दिया गया है
क्रिस


2
Xcode अब इसे पूरा करेगा, बस टाइप करना शुरू करें dispatch_afterऔर एंटर दबाएं
mcfedr

1
टाइपिंग के दौरान विशेष रूप से अब Xcode ऑटोकंप्लीट करता है dispatch_after, यह वास्तव में यह करने के लिए एक सुपर सरल तरीका है, साथ ही आप गुणों को उस पद्धति में पास कर सकते हैं जिसे आप कॉल कर रहे हैं, जो बहुत अच्छा है।
एरिक वैन डेर न्यूट

128

सबसे अच्छा तरीका है:

[self performSelector:@selector(YourFunctionName) 
           withObject:(can be Self or Object from other Classes) 
           afterDelay:(Time Of Delay)];

तुम भी withObject पैरामीटर के रूप में nil पास कर सकते हैं।

उदाहरण :

[self performSelector:@selector(subscribe) withObject:self afterDelay:3.0 ];

3
आप स्वयं को स्वयं क्यों पास करेंगे?
एरिक

2
और आप एक चर को एक विधि से क्यों पारित करेंगे जो शून्य तर्क लेता है?
हेल्लोजिमी

23

पहले से ही बहुत सारे उत्तर हैं और वे सभी सही हैं। यदि आप उपयोग करना चाहते हैं, dispatch_afterतो आपको उस स्निपेट की तलाश होनी चाहिए Code Snippet Library, जो दाईं ओर नीचे (जहां आप UIतत्वों का चयन कर सकते हैं) के अंदर शामिल हो ।

यहां छवि विवरण दर्ज करें

इसलिए आपको कोड में प्रेषण लिखकर इस स्निपेट को कॉल करना होगा :

यहां छवि विवरण दर्ज करें


16

0.1 सेकेंड की देरी विधि कॉल करने के लिए आप निम्न चयनकर्ता का उपयोग कर सकते हैं।

[self performSelector:@selector(InsertView)  withObject:nil afterDelay:0.1]; 

9

आप भी कर सकते हैं:

[UIView animateWithDuration:1.0
                 animations:^{ self.view.alpha = 1.1; /* Some fake chages */ }
                 completion:^(BOOL finished)
{
    NSLog(@"A second lapsed.");
}];

इस मामले में आपको एनीमेशन कार्य प्राप्त करने के लिए कुछ दृश्य में कुछ परिवर्तन नकली करने होंगे। यह वास्तव में हैकी है, लेकिन मुझे ब्लॉक आधारित सामान पसंद है। या नीचे @mcfedr उत्तर को लपेटें।


waitFor(1.0, ^
{
    NSLog(@"A second lapsed");
});

typedef void (^WaitCompletionBlock)();
void waitFor(NSTimeInterval duration, WaitCompletionBlock completion)
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC),
                   dispatch_get_main_queue(), ^
    { completion(); });
}

निश्चित नहीं है, लेकिन मुझे लगता है कि आपके द्वारा सुझाए गए पहले विकल्प के साइड-इफेक्ट्स हो सकते हैं, जिनके बारे में उपयोगकर्ताओं को पता होना चाहिए, जैसे यूआई के कुछ हिस्सों पर यूजर इंटरेक्शन को रोकना। मेरी वृत्ति यह है कि यह कुछ अनावश्यक सीपीयू या अन्य संसाधन नाली का भी कारण होगा, लेकिन मैंने जाँच नहीं की है।
ब्योर्न रोश

8

तुम यह केर सकते हो

[self performSelector:@selector(MethodToExecute) withObject:nil afterDelay:1.0 ];

4

स्विफ्ट 2.x

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
 dispatch_after(delayTime, dispatch_get_main_queue()) {
 print("do some work")
}

स्विफ्ट 3.x - & - स्विफ्ट 4

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    print("do some work")
}

या पास escaping closure

func delay(seconds: Double, completion: @escaping()-> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now() + seconds, execute: completion)
}

1

जाँच किए गए समाधान से एक स्विफ्ट 3 समाधान है:

self.perform(#selector(self.targetMethod), with: self, afterDelay: 1.0)

और विधि है

@objc fileprivate func targetMethod(){

}


-34

नोट: यह आपके पूरे धागे को रोक देगा, न कि केवल एक विधि को।
अपने तरीके से कॉल करने से पहले 1000 एमएस के लिए सोने / प्रतीक्षा / रुकने के लिए कॉल करें?

Sleep(1000); // does nothing the next 1000 mSek

Methodcall(params); // now do the real thing

संपादित करें: उपरोक्त उत्तर सामान्य प्रश्न पर लागू होता है "मैं 1 सेकंड के लिए एक विधि कॉल को कैसे विलंब कर सकता हूं?", जो उत्तर के समय पूछा गया प्रश्न था (मूल प्रश्न के 7 मिनट के भीतर उत्तर दिया गया था: - ))। उस समय भाषा के बारे में कोई जानकारी नहीं दी गई थी, इसलिए कृपया नींद का उपयोग करने के उचित तरीके के बारे में कुतिया बनाना बंद करें I XCode और वर्गों की कमी ...


केवल वर्तमान धागे में, अन्य धागे चलते रहेंगे।
मार्क चारबोन्यू

4
गीज़। मुझे लगता है कि यह कुछ समय के लिए डाउन-वोट क्यों किया गया था, लेकिन बिल्ली ने इसे -27 में किसने देखा और यह तय किया कि इसे दूसरे की आवश्यकता है? क्या -3 या कुछ को आर-पार नहीं मिलता है। केवल "यह आपके पूरे धागे को रोक देगा" कहने के लिए उत्तर को संपादित न करें या इसे लोगों को नीचा दिखाने के बजाय कुछ करें?
अल्बर्ट रेनशॉ

तो क्या होगा यदि आप पूरे धागे को रोकना चाहते हैं? यदि यह एक सभ्य चेतावनी के साथ आता है तो एक वैध विकल्प की तरह लगता है।
विभागीय बी

@AlbertRenshaw मैं आपसे पूरी तरह सहमत हूँ। मैं यहाँ हूँ और इसके ३५ उतार हैं और मैंने उसे अपना वर दिया। मुझे कम प्रतिष्ठित उपयोगकर्ताओं की ओर इतनी बुरी तरह से हमला करना अधिक पसंद है। कोई भी कुछ भी संपादित या निर्दिष्ट नहीं करेगा। मैंने आज एक जवाब देखा है कि वास्तव में डूब गया। एकमात्र गलती जो उस व्यक्ति ने की, वह उद्देश्यपूर्ण भाषा के साथ एक तेज प्रश्न के तहत किया गया है। यदि यह एक बड़ी गलती है, तो मैं उद्देश्य सी प्रश्नों के तहत इतने सारे स्विफ्ट उत्तर दिखाना चाहता हूं।
सोजत बाबू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.