2016-04-24 5 views
6

शुरू करने से पहले, आईओएस/स्विफ्ट पर किसी फ़ंक्शन को समाप्त करने के लिए कैसे प्रतीक्षा करें I मूल रूप से विधियों के लिए है, जिन्हें मेरे दृश्यडिडलोड में कहा जा रहा है। पहला व्यक्ति उपयोगकर्ता की खोज वरीयताओं को प्राप्त करता है और शीर्ष पर चर के लिए वरीयताओं को बचाता है। इसके बाद मैं दूसरे फ़ंक्शन में इन चर के साथ पहुंच और काम करना चाहता हूं। लेकिन जब मैं दूसरे फ़ंक्शन में उन्हें एक्सेस करना चाहता हूं तो अब चर हमेशा शून्य होते हैं।दूसरा एक

मुझे अपने दृश्यडिडलोड को समायोजित करने की आवश्यकता कैसे है, इसलिए दूसरा फ़ंक्शन केवल एक बार निष्पादित किया गया है और मेरा डेटा अनुरोध सफलतापूर्वक किया गया है?

var searchLocation = String() 
var searchLocationCoordinates = [String:Double]() 
var searchRange = Int() 


override func viewDidLoad() { 
    super.viewDidLoad() 

    // Gets the user's search preference 
    getTheSearchLocationAndRange() 

    // Loads the data from the database 
    loadDataFromDatabase() 
} 

मैं सामान पढ़ा है अब तक dispatch_asynch या पूरा हैंडलर के साथ। हो सकता है कि कोई ऐसा कोड पोस्ट कर सके जिसे मैं अपने व्यूडिडलोड में उपयोग कर सकता हूं और इसे काम करता है?

+5

आप ऐसा कहते नहीं है, लेकिन getThSearchLocationAndRange अतुल्यकालिक होना चाहिए? इस मामले में आपको इंतजार नहीं करना चाहिए, जिससे आपका जीयूआई लटकाएगा।इसके बजाय आप पहला फ़ंक्शन पैरामीटर के रूप में पूर्णता ब्लॉक ले सकते हैं और दूसरा फ़ंक्शन डालने के रूप में ब्लॉक बॉडी इसे करने का एक तरीका है, अन्य भी हैं। – Gruntcakes

+0

ठीक है हाँ इसे मिला! क्या आपके पास कुछ नमूना कोड है जो मुझे दिखाता है? लेकिन यह भी एक विचार था जिसे मैंने पूरा पदों के साथ अन्य पदों में देखा था! – Mattk90

+0

क्या TheSearchLocationAndRange पाने में कोई प्रेषण कार्य है? – FredericP

उत्तर

1

ठीक है, मैं एक समाधान मिल गया है। मैंने मूल रूप से पहले के अंत में फ़ंक्शन को बुलाया।

तो मूल रूप से:

var searchLocation = String() 
    var searchLocationCoordinates = [String:Double]() 
    var searchRange = Int() 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Gets the user's search preference 
     getTheSearchLocationAndRange() 
    } 

    func getTheSearchLocationAndRange() { 
    // Code for getTheSearchLocationAndRange() 

    loadDataFromDatabase() 
    } 

    func loadDataFromDatabase(){ 
    // Code for loadDataFromDatabase() 
    } 
+1

लौटाए जाने की आवश्यकता है, इसके साथ समस्या यह है कि यह 'getTheSearchLocationAndRange()' फ़ंक्शन कम उपयोगी बनाता है, जब तक कि यह हमेशा * loadDataFromDatabase' को कॉल नहीं किया जाता है। यदि आप विधि को और अधिक लचीला होना चाहते हैं, तो समापन ब्लॉक विधि का उपयोग करें। – milesper

+0

ठीक है मैं उस बिंदु पर सहमत हूं। मेरे मामले में मुझे स्वतंत्र रूप से दोनों कार्यों की आवश्यकता नहीं होगी। इसलिए मुझे लगता है कि मैं इसे इस तरह हल कर सकता हूं। लेकिन मैं आपको क्रेडिट देता हूं, कि आप प्रोग्राम प्रोग्रामिक रूप से बेहतर हो सकते हैं! hahha – Mattk90

6

आप स्विफ्ट बंद करने का उपयोग कर सकते हैं! वे इसके लिए बने हैं।

कृपया एप्पल मार्गदर्शिका देखें: Closures

यहाँ कोड है कि आप अपने विशेष मामले में की जरूरत है।

समाप्त हुआ डाउनलोड बंद है। जब getTheSearchLocationAndRange() कहा जाता है, तो इसका कोड completed() लाइन तक निष्पादित किया जाता है जो फ़ंक्शन की सभी प्रक्रियाओं को समाप्त करने की प्रतीक्षा करता है। प्रक्रिया समाप्त होने के बाद (उदाहरण के लिए डाउनलोड), completed() बंद करने को कॉल करता है जो getTheSearchLocationAndRange {() ->() in में परिभाषित कोड को सक्रिय करता है। इसलिए, loadDataFromDatabase() केवल एक बार कहा जाता है getTheSearchLocationAndRange() पूरी तरह से निष्पादन समाप्त हो गया है और डेटा मौजूद है (शून्य नहीं)।

var searchLocation = String() 
    var searchLocationCoordinates = [String:Double]() 
    var searchRange = Int() 
    typealias FinishedDownload =() ->() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     getTheSearchLocationAndRange() 
    } 

    func getTheSearchLocationAndRange(completed: FinishedDownload) { 

      // Code for searching Location Range HERE 

      completed() 
    } 

    getTheSearchLocationAndRange {() ->() in 
     loadDataFromDatabase() 
    } 

मुझे आशा है कि यह आपकी समस्या हल हो और

BTW अपने प्रश्न :) उत्तर दिया, "अपने जीयूआई फांसी छोड़ने" भाग के बारे में, Alamofire स्वचालित रूप से आप के लिए यह का ख्याल रखता है। यदि आप अलामोफायर का उपयोग नहीं करते हैं, तो आपको पृष्ठभूमि थ्रेड पर असीमित अनुरोध असाइन करना होगा ताकि आपका जीयूआई उत्तरदायी न हो।

+0

क्या होगा यदि मेरे पास GetTheSearchLocationAndRange में पैरामीटर हैं जो मुझे – Sam

3

मैंने एक डेमो प्रोजेक्ट लिखा और इसे गिटहब पर पोस्ट किया जो एसिंक्रोनस नेटवर्क डाउनलोड को संभालने का अनुकरण करता है। DuncanMC/SwiftCompletionHandlers पर एक नज़र डालें।

विशेष रूप से विधि asyncFetchImage() को देखें, जो लगभग इस धागे के बारे में बात कर रहा है: आंतरिक रूप से एक एसिंक्रोनस विधि का उपयोग करता है, और एक पूर्णता ब्लॉक लेता है जिसे एक बार एसिंक्रोनस लोड किया जाता है।

यह सामान्य पैटर्न है जिसका उपयोग आप करना चाहिए। एक विधि लिखें जो एक पूर्णता ब्लॉक/बंद लेता है। आंतरिक रूप से, उस पद्धति को जो भी एसिंक्रोनस फ़ंक्शन की आवश्यकता है उसे कॉल करें और फिर एसिंक्रोनस विधि कॉल के समापन बंद होने के अंदर से अपना समापन बंद करें।

समारोह asyncFetchImage इस तरह दिखता है:

func asyncFetchImage(imageName imageName: String, 
    completion: (
    image: UIImage?, 
    status: String) ->()) 
{ 
    print("Entering \(#function)") 

    //Simulate a network operation by waiting a few seconds before loading an image 
    let nSecDispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 * Double(NSEC_PER_SEC))) 
    let queue = dispatch_get_main_queue() 
    dispatch_after(nSecDispatchTime, queue) 
    { 
    () -> Void in 
     let result = UIImage(named: imageName) 
     print("Loading image in background") 
     let status = result != nil ? "image loaded" : "Error loading image" 
     print("About to call completion handler") 
     completion(image: result, status: status) 
    } 
    print("Leaving \(#function)") 
} 
संबंधित मुद्दे