स्विफ्ट में एक चर के रूप में एक बंद स्टोर करें


140

ऑब्जेक्टिव-सी में, आप एक ब्लॉक के इनपुट और आउटपुट को परिभाषित कर सकते हैं, उन ब्लॉकों में से एक को स्टोर कर सकते हैं जो एक विधि में पारित हो गए हैं, फिर बाद में इस ब्लॉक का उपयोग करें:

// in .h

    typedef void (^APLCalibrationProgressHandler)(float percentComplete);
    typedef void (^APLCalibrationCompletionHandler)(NSInteger measuredPower, NSError *error);

    // in .m

    @property (strong) APLCalibrationProgressHandler progressHandler;
    @property (strong) APLCalibrationCompletionHandler completionHandler;

    - (id)initWithRegion:(CLBeaconRegion *)region completionHandler:(APLCalibrationCompletionHandler)handler
    {
        self = [super init];
        if(self)
        {
            ...
            _completionHandler = [handler copy];
            ..
        }

        return self;
}

- (void)performCalibrationWithProgressHandler:(APLCalibrationProgressHandler)handler
{
    ...

            self.progressHandler = [handler copy];

     ...
            dispatch_async(dispatch_get_main_queue(), ^{
                _completionHandler(0, error);
            });
     ...
}

तो मैं स्विफ्ट में संतुलन बनाने की कोशिश कर रहा हूं:

var completionHandler:(Float)->Void={}


init() {
    locationManager = CLLocationManager()
    region = CLBeaconRegion()
    timer = NSTimer()
}

convenience init(region: CLBeaconRegion, handler:((Float)->Void)) {
    self.init()
    locationManager.delegate = self
    self.region = region
    completionHandler = handler
    rangedBeacons = NSMutableArray()
}

कंपाइलर को पूर्णहैंडलर की घोषणा की पसंद नहीं है। ऐसा नहीं है कि मैं इसे दोष देता हूं, लेकिन, मैं एक बंद को कैसे परिभाषित करता हूं जिसे स्विफ्ट में बाद में सेट और उपयोग किया जा सकता है?


1
जब आप संकलन करते हैं, तो आपको क्या त्रुटि हो रही है?
द लीलाचैप

जवाबों:


335

संकलक शिकायत करता है

var completionHandler: (Float)->Void = {}

क्योंकि दायाँ हाथ उचित हस्ताक्षर का बंद नहीं है, अर्थात एक फ्लोट तर्क ले रहा है। निम्नलिखित पूरा करने वाले हैंडलर को "कुछ भी नहीं" करने के लिए असाइन करेगा:

var completionHandler: (Float)->Void = {
    (arg: Float) -> Void in
}

और इसे छोटा किया जा सकता है

var completionHandler: (Float)->Void = { arg in }

स्वचालित प्रकार के अनुमान के कारण।

लेकिन आप जो चाहते हैं, वह यह है कि पूरा हैंडलर nil उसी तरह से इनिशियलाइज़ होता है, जैसा कि ऑब्जेक्टिव-सी इंस्टेंस वेरिएबल इनविटेशनल है nil। स्विफ्ट में यह एक वैकल्पिक के साथ महसूस किया जा सकता है :

var completionHandler: ((Float)->Void)?

अब संपत्ति स्वचालित रूप से nil("कोई मूल्य नहीं") के लिए शुरू की जाती है। स्विफ्ट में आप पूरा करने के लिए वैकल्पिक बाइंडिंग का उपयोग कर सकते हैं

if let handler = completionHandler {
    handler(result)
}

या वैकल्पिक जंजीर:

completionHandler?(result)

1
"स्विफ्ट में इसे स्पष्ट रूप से
अलिखित

1
((Float)->Void)!से भिन्न का उपयोग कर रहा है ((Float)->Void)?? पहले ?से nilही डिफ़ॉल्ट के साथ एक अनइंस्टाल्यूटेड वैकल्पिक की घोषणा नहीं करता है ?
सुरगाच

43

उद्देश्य सी

@interface PopupView : UIView
@property (nonatomic, copy) void (^onHideComplete)();
@end

@interface PopupView ()

...

- (IBAction)hideButtonDidTouch:(id sender) {
    // Do something
    ...
    // Callback
    if (onHideComplete) onHideComplete ();
}

@end

PopupView * popupView = [[PopupView alloc] init]
popupView.onHideComplete = ^() {
    ...
}

तीव्र

class PopupView: UIView {
    var onHideComplete: (() -> Void)?

    @IBAction func hideButtonDidTouch(sender: AnyObject) {
        // Do something
        ....
        // Callback
        if let callback = self.onHideComplete {
            callback ()
        }
    }
}

var popupView = PopupView ()
popupView.onHideComplete = {
    () -> Void in 
    ...
}

1
लेकिन क्या स्मृति प्रबंधन स्वचालित रूप से सही है? क्योंकि ओब्ज-सी में आप उस संपत्ति को "कॉपी" होने के लिए निर्दिष्ट करते हैं, लेकिन तेजी से लगता है कि यह विकल्प नहीं है और इसे इसके बजाय "मजबूत" के रूप में परिभाषित किया गया है, या यह करता है?
पॉलियस विन्डज़िगेल्किस

इसे कॉपी करने की आवश्यकता क्यों है?
दिमित्री

9

मैंने एक उदाहरण प्रदान किया है, यदि आपको पता नहीं है कि यह क्या है।

var completionHandler: (_ value: Float) -> ()

func printFloat(value: Float) {
    print(value)
}

completionHandler = printFloat

completionHandler(5)

यह केवल completionHandlerघोषित चर का उपयोग करके 5 प्रिंट करता है।


7

में स्विफ्ट 4 और 5 । मैंने एक क्लोजर वैरिएबल बनाया जिसमें दो पैरामीटर डिक्शनरी और बूल हैं।

 var completionHandler:([String:Any], Bool)->Void = { dict, success  in
    if success {
      print(dict)
    }
  }

क्लोजर चर को कॉल करना

self.completionHandler(["name":"Gurjinder singh"],true)

5

क्लोजर typealiasको नीचे के रूप में घोषित किया जा सकता है

typealias Completion = (Bool, Any, Error) -> Void

यदि आप कोड में कहीं भी अपने फ़ंक्शन का उपयोग करना चाहते हैं; आप सामान्य चर की तरह लिख सकते हैं

func xyz(with param1: String, completion: Completion) {
}

3

यह भी काम करता है:

var exeBlk = {
    () -> Void in
}
exeBlk = {
    //do something
}
//instead of nil:
exeBlk = {}

-1

मेरे लिए निम्नलिखित काम कर रहा था:

var completionHandler:((Float)->Void)!
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.