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


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.