2015-03-07 12 views
17

Tại sao tôi có thể có một mảng [AnyObject] và đặt một loạt các loại kích thước khác nhau trong đó ...Tại sao các số nguyên không tuân theo giao thức AnyObject?

var a = [AnyObject]() 
a.append(Int(1)) 
a.append(Float64(3.14)) 
a.append(Bool(true)) 

... trừ Int32Int64 ....

a.append(Int32(1)) // err: type 'Int32' does not conform to protocol 'AnyObject' 
a.append(Int64(1)) // err: type 'Int64' does not conform to protocol 'AnyObject' 

Các tài liệu cho AnyObject nói:

"AnyObject có thể đại diện cho một cá thể của bất kỳ loại lớp nào"

Nhưng khi tôi chỉ huy-click vào Int, Int32 hoặc Int64 để xem định nghĩa thư viện tiêu chuẩn của các loại, tôi thấy rằng họ là tất cả struct giá trị.

Vấn đề cơ bản ở đây là gì? Tại sao điều này được thiết kế như thế này?

Trả lời

24

Có hai loại định dạng bất cứ điều gì trong Swift - Any, mà thực sự có thể giữ bất cứ điều gì - một struct, enum hoặc lớp học, và AnyObject, mà chỉ có thể tổ chức các lớp.

Lý do tại sao nó có vẻ như AnyObject có thể giữ cấu trúc đôi khi là một số loại cụ thể được chuyển đổi hoàn toàn sang NSEquivalent của họ cho bạn khi cần, để làm cho Objective-C interop ít đau đớn hơn.

Khi bạn viết let ao: AnyObject = Int(1), không phải là thực sự đặt Int vào AnyObject. Thay vào đó, nó chuyển đổi hoàn toàn số Int của bạn thành một số NSNumber, là một lớp và sau đó đặt nó vào.

Nhưng chỉ một số loại có chuyển đổi tiềm ẩn này. Int có, nhưng Int32 không, do đó hành vi này:

// fine 
let aoInt: AnyObject = Int(1) as NSNumber 
// also fine: implicit conversion 
let aoImplicitInt: AnyObject = Int(1) 
// not fine: error: 'Int32' is not convertible to 'NSNumber' 
let aoInt32: AnyObject = Int32(1) as NSNumber 
// but the implicit error is less, ahem, explicit 
// error: type 'Int32' does not conform to protocol 'AnyObject' 
let aoImplicitInt32: AnyObject = Int32(1) 

Có thể lập luận có nên chuyển đổi tiềm ẩn hơn để bôi trơn các bánh xe, nhưng sau đó một lần nữa, những chuyển đổi ngầm là nguồn gốc của nhiều sự nhầm lẫn đã và hướng trong bản beta mới nhất là có ít người trong số họ hơn là nhiều hơn.

+0

Cảm ơn bạn đây là một câu trả lời xuất sắc. Bạn có biết liệu có bất kỳ tài liệu nào về loại chuyển đổi tiềm ẩn nào không? Tôi cho rằng điều này vượt xa chỉ là 'NSInteger'. –

+0

Yup, nó được đề cập trong [Sử dụng Swift với Cocoa và Objective-C] (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/ uid/TP40014216-CH6-XID_42) iBook. Nhưng hãy lưu ý rằng nó đã thay đổi trong phiên bản Xcode 6.3 beta và cuốn sách chỉ phản ánh hành vi phiên bản phát hành, vì vậy tốt nhất bạn nên kiểm tra ghi chú phát hành Xcode khi bạn thử nâng cấp. –

+0

BTW Bạn có nghĩa là NSNumber chứ không phải NSInteger tôi giả định? –

0

Giao thức cung cấp cho Int et al khả năng này là _ObjectiveCBridgeable, trong đó you can adopt yourself nếu bạn cảm thấy mạo hiểm.

+0

Điều này phải là bình luận – ketan

+0

Danh tiếng không đủ. Ngoài ra, nó có vẻ như nó trả lời câu hỏi không? – user2488730

0

Vì Int là một loại giá trị.

AnyObject đề cập đến loại referance loại (lớp) không giá trị

Bất kỳ đề cập đến loại referance + kiểu giá trị (struct + lớp)

Bạn phải sử dụng Bất kỳ cho valueTypes, không phải AnyObject

Loại giá trị> thường là cấu trúc, enums, bla bla ..

loại referance> nói chung là lớp

Có hai loại biến> loại referance và các loại giá trị

loại referance là loại con trỏ và thường chứa một giá trị địa chỉ ram nơi dữ liệu gốc được lưu trữ

Loại giá trị không phải là địa chỉ. Họ trực tiếp chứa các giá trị biến

Int asd = 3 (asd trực tiếp chứa 3)

Int, phao, các loại số ... ngày được hầu như luôn luôn struct (kiểu giá trị) trong hầu hết các ngôn ngữ máy tính.

String là gần như luôn luôn là một lai trong hầu hết các ngôn ngữ máy tính

ViewControllers, Views, Buttons, ... mảng, từ điển, ... và tùy chỉnh được xác định lớp học của bạn là loại referance

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