2016-01-21 16 views
15

Trong Swift, làm cách nào để AnyObject hỗ trợ các bảng con, ngay cả đối với các loại không thể lập chỉ mục? Ví dụ:Chỉ số của Swift AnyObject, nó đến từ đâu?

let numbers: AnyObject = [11, 22, 33] 
numbers[0]  // returns 11 

let prices: AnyObject = ["Bread": 3.49, "Pencil": 0.5] 
prices["Bread"] // returns 3.49 

let number: AnyObject = 5 
number[0]  // return nil 

let number: AnyObject = Int(5) 
number[0]  // return nil 

Tuy nhiên, nếu number tôi được khai báo là Int thì đó là một lỗi cú pháp:

let number: Int = 5 
number[0]  // won't compile 

Điều thú vị là, Any không có hỗ trợ subscript.

+0

liên quan: http://stackoverflow.com/questions/24154304/why-is-an-array-an-anyobject-in-swift – dfri

+0

câu hỏi đặt ra là rất thú vị để hiểu những điều đằng sau hậu trường nhưng khá lý thuyết. Trong thực tế, bạn sẽ không sử dụng chú thích kiểu 'AnyObject' cho một đối tượng có trình biên dịch thích hợp có thể suy ra và bạn - nhà phát triển - biết chính xác.Apple mạnh mẽ không khuyến khích sử dụng các loại chú thích kiểu như vậy. – vadian

+1

'NSJSONSerialization.JSONObjectWithData' trả về' AnyObject' –

Trả lời

5

Nó đã làm với các cầu nối của các loại khi gán một giá trị cho một đối tượng kiểu AnyObject:

let numbers: AnyObject = [11, 22, 33] 
print(numbers.dynamicType) // _SwiftDeferredNSArray.Type 

let prices: AnyObject = ["Bread": 3.49, "Pencil": 0.5] 
print(prices.dynamicType) // _NativeDictionaryStorageOwner<String, Double>.Type 

let number: AnyObject = 5 
print(number.dynamicType) // __NSCFNumber.Type 

let anotherNumber: Int = 5 
print(anotherNumber.dynamicType) // Int.Type 

Đằng sau hậu trường, _SwiftDeferredNSArray.Type, _NativeDictionaryStorageOwner<String, Double>.Type, và __NSCFNumber.Type phải hỗ trợ kí hiệu trong khi Int.Type không.

Giả sử bạn đã nhập Foundation. Để được giải thích về các loại Swift thuần túy, hãy xem Cristik's answer.

12

Điều này chỉ hoạt động nếu bạn nhập Foundation, như Swift đang thực hiện trong trường hợp đó một số cầu nối đến Objective-C loại - một đối tượng giống như NSArray trong trường hợp này.

import Foundation 

let numbers: AnyObject = [11, 22, 33] 
numbers.dynamicType //_SwiftDeferredNSArray.Type 

Nếu bạn không nhập Foundation, sau đó bạn thậm chí không được phép thực hiện việc chuyển nhượng (vì một mảng Swift là một cấu trúc và không phải là một đối tượng).

let numbers: AnyObject = [11, 22, 33] // error: contextual type 'AnyObject' cannot be used with array literal 

Bạn có thể đúc để Any, mặc dù:

let numbers: Any = [11, 22, 33]  
numbers.dynamicType // Array<Int>.Type 

Tại sao import Foundation hiện các trick? Đây là tài liệu trong mô tả AnyObject loại:

/// When used as a concrete type, all known `@objc` methods and 
/// properties are available, as implicitly-unwrapped-optional methods 
/// and properties respectively, on each instance of `AnyObject`. For 
/// example: 
/// 
///  class C { 
///  @objc func getCValue() -> Int { return 42 } 
///  } 
/// 
///  // If x has a method @objc getValue()->Int, call it and 
///  // return the result. Otherwise, return nil. 

này có nghĩa là bạn thậm chí có thể gọi các phương thức trên mảng của bạn mà không nhất thiết phải tồn tại trên NSArray, nhưng tồn tại trong thế giới Objective-C, ví dụ như:

numbers.lowercaseString  // nil 

và Swift sẽ trả lại giá trị nil một cách duyên dáng thay vì ném cho bạn một ngoại lệ khó chịu object does not recognises selector, giống như nó sẽ xảy ra trong Mục tiêu-C. Nếu điều này là tốt hay xấu, vẫn còn tranh luận :)

Cập nhật dường như ở trên để làm việc chỉ dành cho tài sản, và các phương pháp tài sản như thế nào, nếu bạn cố gắng sử dụng một phương pháp Objective-C, sau đó bạn sẽ chạy vào vấn đề chọn không được công nhận:

import Foundation 

@objc class TestClass: NSObject { 
    @objc var someProperty: Int = 20 
    @objc func someMethod() {} 
} 

let numbers: AnyObject = [11, 22, 33] 
numbers.lowercaseString    // nil 
numbers.someMethod      // nil 
numbers.someMethod()     // unrecognized selector 
numbers.stringByAppendingString("abc") // unrecognized selector 
+0

Tìm thấy tuyệt vời và một câu trả lời tuyệt vời. Câu trả lời của tôi cho rằng Foundation đã được nhập. Cảm ơn bạn đã giải thích Swift thuần túy! – JAL

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