2014-07-07 17 views
87

Trong Objective-C, bạn có thể xác định đầu vào và đầu ra của một khối, lưu trữ một trong những khối đó là thông qua vào một phương pháp, sau đó sử dụng khối sau:cửa hàng đóng cửa như là một biến trong Swift

// 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); 
      }); 
    ... 
} 

Vì vậy, tôi đang cố gắng làm việc bình đẳng trong Swift:

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() 
} 

Trình biên dịch không thích tuyên bố hoàn thànhHandler đó. Không phải là tôi đổ lỗi cho nó, nhưng, làm thế nào để tôi xác định một đóng cửa có thể được thiết lập và sử dụng sau này trong Swift?

+1

lỗi bạn đang nhận được gì, khi bạn biên dịch? – TheLazyChap

Trả lời

245

Trình biên dịch phàn nàn về

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

vì phía bên phải không phải là một kết thúc của chữ ký phù hợp, tức là đóng cửa lấy một cuộc tranh luận phao. Sau đây sẽ gán một "không làm gì cả" đóng cửa để xử lý hoàn thành:

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

và điều này có thể được rút ngắn xuống còn

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

do những suy luận kiểu tự động.

Nhưng những gì bạn có thể muốn là xử lý hoàn thành được khởi tạo để nil trong cùng một cách mà một biến Ví dụ Objective-C được inititialized để nil. Trong Swift này có thể được thực hiện với một tùy chọn:

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

Bây giờ bất động sản được tự động khởi tạo nil ("không có giá trị"). Trong Swift bạn sẽ sử dụng tùy chọn ràng buộc để kiểm tra của một handler hoàn thành có giá trị

if let handler = completionHandler { 
    handler(result) 
} 

hoặc chaining tùy chọn:

completionHandler?(result) 
+78

Điều đó giải quyết nó. Tôi muốn upvote câu trả lời của bạn, nhưng là một newbie, tốt nhất tôi có thể làm là có lẽ tên một biến trong nguồn của tôi trong danh dự của bạn. –

+1

"Trong Swift, điều này có thể được thực hiện với một tùy chọn chưa được mở" "một cách rõ ràng chưa được mở" (tức là thường xuyên) tùy chọn – newacct

+1

Đang sử dụng '((Float) -> Void)!' Khác với '((Float) -> Void)? '? Không khai báo một tùy chọn uninitialized với '?' Mặc định là 'nil'? – Suragch

3

Tôi đã cung cấp một ví dụ không chắc chắn nếu đây là những gì bạn đang theo dõi.

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

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

completionHandler = printFloat 

completionHandler(value: 5) 

Nó chỉ in 5 bằng cách sử dụng biến completionHandler được khai báo.

-1

Đối với tôi sau đây đang làm việc:

var completionHandler:((Float)->Void)! 
23

Mục tiêu-C

@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 = ^() { 
    ... 
} 

Swift

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

Nhưng quản lý bộ nhớ có được xử lý tự động chính xác không? Bởi vì trong Obj-C Bạn chỉ định thuộc tính đó là "sao chép", nhưng nhanh chóng dường như không có tùy chọn đó và được định nghĩa là "mạnh" thay vào đó, hay không? –

1

này hoạt động quá:

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

đóng cửa có thể được khai báo là typealias như sau

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

Nếu bạn muốn sử dụng trong chức năng của bạn bất cứ nơi nào trong mã; bạn có thể viết như biến bình thường

func xyz(with param1:String,completion:Completion) { 
} typealias Completion = (Bool,Any,Error)->Void 
1

Nhanh chóng 4. Tôi tạo biến đóng có chứa hai từ điển tham số và bool.

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

Gọi đóng cửa biến

self.completionHandler(["name":"Gurjinder singh"],true) 
Các vấn đề liên quan