সুইফটে চলক হিসাবে একটি ক্লোজার সংরক্ষণ করুন


140

অবজেক্টিভ-সিতে, আপনি একটি ব্লকের ইনপুট এবং আউটপুট সংজ্ঞায়িত করতে পারেন, কোনও পদ্ধতিতে পাস করা blocks ব্লকগুলির একটি সংরক্ষণ করতে পারেন, তারপরে সেই ব্লকটি পরে ব্যবহার করুন:

// 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
সংকলন করার সময় আপনি কোন ত্রুটি পাচ্ছেন?
— TheLazyChap

উত্তর:


334

সংকলকটি অভিযোগ করে

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

কারণ ডানদিকের দিকটি উপযুক্ত স্বাক্ষরের বন্ধ হওয়া নয়, অর্থাত্ একটি ভাসা যুক্তি গ্রহণ করা বন্ধ। নিম্নলিখিতটি সম্পূর্ণরূপে হ্যান্ডলারের একটি "কিছুই করবেন না" বন্ধের দায়িত্ব দেবে:

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

এবং এটি সংক্ষিপ্ত করা যেতে পারে

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

স্বয়ংক্রিয় টাইপ অনুমানের কারণে।

তবে আপনি সম্ভবত যা চান তা হ'ল সমাপ্তি হ্যান্ডলারটি nil একইভাবে আরম্ভ করা হবে যেহেতু একটি উদ্দেশ্য-সি উদাহরণ ভেরিয়েবলটি আরম্ভ করা হয় nil। সুইফটে এটি একটি option চ্ছিক মাধ্যমে উপলব্ধি করা যায় :

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

এখন সম্পত্তিটি স্বয়ংক্রিয়ভাবে nil("কোনও মূল্য নেই") এ সূচনা হবে । সুইফটে আপনি একটি সম্পূর্ণতা হ্যান্ডলারের একটি মান আছে কিনা তা পরীক্ষা করতে alচ্ছিক বাঁধাই ব্যবহার করবেন

if let handler = completionHandler {
    handler(result)
}

বা alচ্ছিক শৃঙ্খলা:

completionHandler?(result)


1
এর ((Float)->Void)!চেয়ে আলাদা কি ব্যবহার করছে ((Float)->Void)?? সঙ্গে একটি uninitialized ঐচ্ছিক ঘোষণা না ?ডিফল্ট 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

আমি একটি উদাহরণ প্রদান করেছি যে এটি আপনার পরে কী তা নিশ্চিত কিনা not

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)!
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.