2016-03-22 17 views
36

Tôi đang chuyển đổi cú pháp của dự án sang Swift 2.2 (xCode giúp tôi tự động làm); tuy nhiên, tôi không hiểu cú pháp mới #selector().Hiểu Swift 2.2 Cú pháp chọn - #selector()

Như một ví dụ:

timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, 
      selector: #selector(MyVC.timerCalled(_:)), //new selector syntax! 
      userInfo: nil, repeats: true) 

này được chọn #selector(MyVC.timerCalled(_:))

nào _: ý nghĩa gì? Bạn có thể thêm các biến khác vào bộ chọn này không? Nói, #MyVC.timerCalled(_:whateverVar).

Thông tin chung về những gì khác biệt trong cú pháp này trái ngược với việc triển khai chuỗi dựa trên các phiên bản trước của Swift được đánh giá cao.

+2

Tôi nghĩ rằng tôi giải thích nó độc đáo ở đây: http://stackoverflow.com/questions/35658334/how-do-i-resolve-ambiguous-use-of-compile-error-with-swift-selector-syntax/35658335# 35658335 – matt

+0

@ matt's trả lời địa chỉ cú pháp kỹ lưỡng hơn, bao gồm một cuộc thảo luận hữu ích về đối phó với các phương pháp quá tải. – Stuart

Trả lời

31

Các bit trong ngoặc là một cơ chế để xác định danh sách đối số cho bộ chọn mà bạn muốn.

Tôi khuyên bạn nên xem xét đề xuất Generalized Naming từ Swift Evolution. Nó bao gồm các trường hợp bạn có một số hàm chỉ khác nhau bởi các nhãn tham số của chúng và cần tham chiếu đến chúng. Ví dụ từ tài liệu đó là:

extension UIView { 
    func insertSubview(view: UIView, at index: Int) 
    func insertSubview(view: UIView, aboveSubview siblingSubview: UIView) 
    func insertSubview(view: UIView, belowSubview siblingSubview: UIView) 
} 

Nếu bạn muốn để có được một giá trị hàm cho một trong những kết quả là mơ hồ:

let fn = someView.insertSubview // ambiguous: could be any of the three methods 

Các giải pháp thực hiện là thêm nhãn cãi nhau, mà không cần bất kỳ nhập thông tin vào mã tạo ra giá trị hàm để phân biệt bạn muốn:

let fn = someView.insertSubview(_:at:) 
let fn1 = someView.insertSubview(_:aboveSubview:) 

Xem cách nhãn được thêm vào trong parens?

Đề xuất này đã đóng một vai trò trong một trong đó áp dụng trực tiếp nhất cho câu hỏi của bạn:

Referencing the Objective-C selector of a method

Trong trường hợp này bộ chọn bạn muốn đề cập đến là timerCalled: mà là một chức năng của một tham số mà không có nhãn. Vì thế (_:). Dấu gạch dưới nghĩa là nhãn không được chỉ định và dấu hai chấm.

8

Đây là cách chữ ký Swift được thể hiện trong tài liệu và bây giờ bắt đầu được sử dụng trong các tính năng ngôn ngữ mới như cú pháp #selector() để thể hiện các phương thức theo danh sách đối số của chúng.

Mỗi dấu hai chấm (:) đại diện cho tham số phương thức. Đối với các tham số được đặt tên, dấu hai chấm đứng trước tên thông số bên ngoài; đối với các thông số chưa đặt tên, dấu gạch dưới (_) được sử dụng.

Vì vậy, ví dụ, MyVC.timerCalled(_:)) chỉ ra một phương pháp vào loại MyVC với một tham số không rõ tên, mà có thể được khai báo như thế này:

func timerCalled(timer: NSTimer) { ... } 

(Lưu ý rằng timer là tên tham số nội, vì theo mặc định tham số đầu tiên của phương thức không được đặt tên)

Loại (MyVC trong ví dụ của bạn) cũng có thể bị bỏ qua nếu nằm trong cùng phạm vi của tuyên bố #selector().

Một ví dụ phức tạp hơn có thể trông như thế này:

let sel = #selector(aMethodWithSeveralParameters(_:secondParam:thirdParam:)) 

... 

func aMethodWithSeveralParameters(firstParam: Int, secondParam: Int, thirdParam: Int) { ... } 
19

Swift 2.2 đã không dùng nữa Bộ chọn được chọn: Trong 2.0 nhanh, chúng tôi sử dụng để viết bộ chọn làm Chuỗi là "buttonClicked". Điểm bất lợi của phương pháp này là trình biên dịch không thể kiểm tra xem phương thức thực sự tồn tại hay không ở thời gian biên dịch (Ngay cả khi bạn đã viết sai chính tả nó).

EX: 1

func buttonClicked(){ 
} 

Vì vậy, các phương pháp trên trong cách tiếp cận mới có thể được gọi là #selector(buttonClicked)

EX: 2

func buttonClicked(stringValue : String){ 
} 

Vì vậy, các phương pháp trên trong cách tiếp cận mới có thể được gọi là #selector(buttonClicked(_:))

EX: 3

func buttonClicked(stringValue : String, indexValue : Int){ 
} 

Vì vậy, các phương pháp trên với các thông số trong cách tiếp cận mới có thể được gọi là #selector(buttonClicked(_:indexValue:))

+0

Xin chào, tôi vừa mới đọc câu hỏi này. Bạn có thể vui lòng giải thích ngắn gọn cho tôi lý do tại sao trình biên dịch sẽ sửa/thay đổi ví dụ trên của bạn thành #selector (YourClass.buttonClicked) thay vì chỉ #selector (buttonClicked) khi chuyển đổi sang swift 2.2. Có sự khác biệt giữa 2? Cảm ơn bạn – crashoverride777

+0

@ crashoverride777 tôi nghĩ rằng câu hỏi của bạn đã được giải thích rõ ràng ở đây .. http://stackoverflow.com/questions/24007650/selector-in-swift?rq=1 –

+0

Tôi nghĩ bạn luôn cần tiền tố khai báo phương thức với @objc – blackjacx

9

xem xét bên dưới mã cho thêm mục tiêu để nút trong nhanh chóng 3 sử dụng #selector

button.addTarget(self, action: #selector(self.buttonAction(sender:)), 
         for: UIControlEvents.touchUpInside) 

func buttonAction(sender:UIButton!){ 

} 

Cú pháp này làm việc cho tôi khi di chuyển đến swift 3

+0

Câu hỏi là về VERSION 2 ... – FonzTech