2014-06-14 32 views
34

Trong chữ ký hàm Swift, số ! sau một đối số ngụ ý là gì? Cụ thể hơn, có nghĩa là các lập luận cần được tháo trước khi nó được thông qua vào hoặc là nó bị tháo (tự động) khi nó được thông qua năm Dưới đây là một ví dụ:.Trong Swift, cái gì! biểu tượng có nghĩa là trong một chữ ký chức năng?

func annotationButtonTUI(sender: UIButton!) { } 

Trong trường hợp này chức năng là một nhắm mục tiêu cho UIButton vì vậy bất kỳ điều gì xảy ra với ! sẽ tự động diễn ra.

Suy nghĩ của tôi là điều đó có nghĩa là bạn có thể mong đợi một đối tượng chưa được mở sender để bạn không cần phải thử mở nó ra.

Trả lời

34

Điều này không hoàn toàn trùng lặp - có một số sự tinh tế với các tùy chọn không được mở hoàn toàn trong các chữ ký chức năng ngoài việc sử dụng chúng ở nơi khác.

Bạn thấy các tùy chọn không được mở hoàn toàn trong API được nhập từ ObjC vì đó là xấp xỉ gần đúng nhất Swift của một đối tượng được mong đợi ở đó nhưng có thể là không. Đó là một sự thỏa hiệp cho API được nhập - bạn có thể xử lý các biến này trực tiếp như trong ObjC và bạn có thể kiểm tra chúng cho nil bằng cú pháp tùy chọn Swift. (Có nhiều hơn về lý do của Apple cho điều này trong Advanced Interoperability talk từ WWDC14.) Mẫu này cũng áp dụng cho các khai báo IBAction được chèn bởi Trình tạo giao diện, vì các phương thức đó có hiệu lực cũng được gọi từ mã ObjC. Khi bạn dường như đã nghi ngờ, Swift sẽ kết thúc tốt nhất có thể trong một tùy chọn khi bắc cầu từ ObjC, nhưng ! trong khai báo triển khai chức năng của bạn sẽ mở khóa giá trị để bạn có thể sử dụng nó trực tiếp. (Có nguy cơ của riêng bạn.)

Kể từ Swift 1.2 (Xcode 6.2 vào mùa xuân 2015), API ObjC có thể được chú thích với nonnullnullable, trong trường hợp giao diện Swift cho các API đó sử dụng loại không bắt buộc hoặc loại tùy chọn hoàn toàn. (Và kể từ Swift 2.0/Xcode 7.0, gần như tất cả các API của Apple đều được kiểm tra để sử dụng chú thích vô hiệu, vì vậy chữ ký Swift của chúng không sử dụng nhiều hơn ! nữa.)

Điều ít nổi tiếng hơn về điều này là bạn tự do thay đổi tùy chọn tham số khi bạn triển khai các hàm Swift của riêng bạn mà ObjC gọi. Nếu bạn muốn trình biên dịch thực thi rằng sender trong phương thức hành động của bạn không bao giờ có thể là 0, bạn có thể loại bỏ loại tham số !. Nếu bạn muốn trình biên dịch đảm bảo bạn luôn kiểm tra tham số, hãy thay đổi ! thành ?.

+1

Bạn nói đúng, nhưng kể từ phiên bản beta 6 Apple đã bắt đầu bằng cách nào đó ảnh hưởng đến việc lập bản đồ API của họ. Khi chúng ghi chú trong các ghi chú phát hành: 'Một số lượng lớn các API Foundation đã được kiểm tra cho sự phù hợp tùy chọn, loại bỏ một số lượng đáng kể các tùy chọn được gỡ bỏ hoàn toàn khỏi giao diện của chúng. Điều này làm rõ tính vô dụng của các thuộc tính và các đối số của chúng/các giá trị trả về của các phương thức của chúng. Đây là nỗ lực không ngừng kể từ phiên bản beta 5.' Bất kỳ ý tưởng nào về cách chúng tôi có thể thực hiện tương tự cho các API tùy chỉnh của mình? – Klaas

7

Dấu chấm than sau khi khai báo kiểu trong ký hiệu phương thức Swift có nghĩa là tham số là Implicitly Unwrapped Optional. Điều đó có nghĩa là nó là một Optional type (thường được ký hiệu là ? sau loại) được mở ra mỗi khi bạn truy cập nó trong phần thân phương thức. Không phải là nó được thông qua. Nó giống như khi bạn sử dụng forced unwrapping - sender!.titleLabel - mỗi khi bạn sử dụng nó, nhưng bạn không phải gõ dấu chấm than mỗi lần - do đó ẩn hoàn toàn tùy chọn.

Từ Using Swift with Cocoa and Objective-C, section Working with nil:

Bởi vì Objective-C không thực hiện bất kỳ đảm bảo rằng một đối tượng là phi nil, Swift làm cho mọi tầng lớp trong loại đối số và kiểu trả về tùy chọn trong API Objective-C nhập khẩu. Trước khi bạn sử dụng một đối tượng Objective-C, bạn nên kiểm tra để đảm bảo rằng nó không bị thiếu.

Tùy chọn ẩn hoàn toàn cho phép bạn xử lý nó trong mã Swift như một loại giá trị bình thường với cảnh báo truy cập khi nó là nil sẽ làm gián đoạn chương trình của bạn với lỗi thời gian chạy. Bạn bảo vệ chống lại điều đó bằng cách sử dụng if statements, optional binding hoặc optional chaining.

Các tùy chọn không được khai thác hoàn toàn là sự thỏa hiệp thực dụng để làm cho công việc trong môi trường lai phải tương thích với các khung công tác Cocoa hiện tại và các quy ước của chúng dễ chịu hơn, đồng thời cho phép di chuyển từng bước vào mô hình lập trình an toàn hơn. trình biên dịch. Bạn sẽ gặp họ trên tất cả các API Cocoa, nhưng cũng có một số số use cases for them in pure Swift như đã được thảo luận trong Why create "Implicitly Unwrapped Optionals"?

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