2014-06-28 18 views
36

tôi đang học Swift lang, nhưng tôi không thể vượt qua lý luận gọi lại tùy chọn vào chức năng:Đi qua gọi lại tùy chọn vào chức năng Swift

func dismiss(completion:() -> Void) { 
    if (completion) { 
     return self.dismissViewControllerAnimated(true, completion: completion) 
    } 
    self.dismissModalViewControllerAnimated(true) 
} 

Điều này cho thấy tôi một lỗi - Type() -> Void does not conform to protocol 'LogicValue'

Bất kỳ lời đề nghị?

Trả lời

44

Cập nhật cho Swift 3/4:

Một tùy chọn không còn là một biểu thức boolean, và phản func dismissModalViewControllerAnimated(animated: Bool) không còn có sẵn trong Swift.

Đơn giản chỉ cần khai báo thông số hoàn thành như một kết thúc không bắt buộc, và vượt qua nó trên để

func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) 

mà phải mất một đóng cửa không bắt buộc cũng như:

func dismiss(completion: (() -> Void)? = nil) { 
    self.dismiss(animated: true, completion: completion) 
} 

Cũ (Swift 1 .x?) answer:

Khai báo các tham số completion như (ngầm nào) tùy chọn đóng cửa (() -> Void)!:

func dismiss(completion: (() -> Void)!) { 
    if (completion) { 
     return self.dismissViewControllerAnimated(true, completion: completion) 
    } 
    self.dismissModalViewControllerAnimated(true) 
} 

Nhưng lưu ý rằng bạn có thể gọi

self.dismissViewControllerAnimated(true, completion: completion) 

trong mọi trường hợp, vì completion tham số của chức năng đó là tùy chọn như tốt. Và

func dismissModalViewControllerAnimated(animated: Bool) 

thực sự được đánh dấu là không dùng nữa.

+1

Trong trường hợp này cụ thể đó là không quá quan trọng, nhưng lưu ý rằng việc sử dụng tùy chọn ẩn hoàn toàn sẽ gây ra sự cố nếu bạn quên kiểm tra nil trước khi gọi nó. Trong khi nếu bạn sử dụng một tùy chọn thường xuyên như trong câu trả lời của ninja mã, trình biên dịch giúp bạn tiết kiệm từ chính mình và bạn buộc bạn phải hoàn thành viết?() (Không sụp đổ nếu hoàn thành là số không. –

+0

Bạn có thể giải thích tại sao '(() -> Void)! 'Định nghĩa một đóng cửa tùy chọn? Từ những gì tôi đã học được cho đến nay, sẽ không cố gắng này để unwrap một giá trị nil gây ra một lỗi thời gian chạy nếu bạn thông qua một xử lý hoàn thành nil trong? –

+1

@MatthewCawley: Một tùy chọn ẩn hoàn toàn là một tùy chọn là tốt, và có, bạn phải kiểm tra nó nếu nó có thể là nil, đó là những gì 'if (completion)' đã làm. Câu trả lời ở trên khá cũ (Swift 1.x) và tôi phải thừa nhận rằng tôi không nhớ tại sao tôi chọn IUO thay vì tùy chọn mạnh. Có lẽ đó là kiểu tham số của 'func dismissViewControllerAnimated (_: completion:)' tại thời điểm đó. - Nhưng mã đã lỗi thời và sẽ không biên dịch nữa, tôi đã cập nhật nó cho Swift hiện tại. –

15

Chỉ cần thêm vào câu trả lời Martin R của trên ..

Việc gọi lại có thể tùy chọn, thay vì tham số ẩn (với dấu chấm than), sử dụng các nhà điều hành tùy chọn.

func dismiss(completion: (() -> Void)?) { 
    if completion != nil { 
     return self.dismissViewControllerAnimated(true, completion: completion!) 
    } 

    self.dismissModalViewControllerAnimated(true) 
} 
+0

Mã của bạn có chức năng khác với mã Martin R không? Có vẻ như một cách logic. –

+0

Đó là một cách hợp lý 'giống nhau' mặc dù bạn có thể cho rằng cú pháp của việc sử dụng hàm này là khác nhau. –

+0

Cảm ơn. Chỉ muốn chắc chắn rằng tôi đã hiểu. –

9

Nó tốt hơn để thêm = nil trong tờ khai gọi lại, để tránh đi qua con số không trong khi gọi đó là:

func dismiss(completion: (() -> Void)? = nil) { 
    if (completion) { 
     return self.dismissViewControllerAnimated(true, completion: completion) 
    } 
    self.dismissModalViewControllerAnimated(true) } 

Và bạn có thể gọi chức năng của bạn như thế này: dismiss()

Các vấn đề liên quan