2015-03-07 3 views
17

Почему я могу иметь [AnyObject] массив и поставить кучу разных размеров типов в нем ...Почему целые числа не соответствуют протоколу AnyObject?

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

... для Int32 и Int64 ....

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' 

Документация, кроме для AnyObject говорит:

«AnyObject может представлять собой экземпляр любого типа класса»

Но когда я приказываю кнопку мыши на Int, Int32 или Int64 увидеть стандартное определение библиотеки этих типов, я вижу, что они все struct значения.

В чем проблема? Почему это так устроено?

ответ

24

В Swift есть два типа любых типов: 0 - Any, которые могут действительно содержать что угодно - структуру, перечисление или класс и AnyObject, которые могут содержать только классы.

Причина, по которой кажется, что AnyObject может содержать структуры, заключается в том, что некоторые конкретные типы неявно преобразуются в их NSEquivalent для вас по мере необходимости, чтобы сделать Objective-C interop менее болезненным.

Когда вы пишете let ao: AnyObject = Int(1), не действительно положить Int в AnyObject. Вместо этого он неявно преобразовывает ваш Int в NSNumber, который является классом, а затем помещает его.

Но только некоторые типы имеют это неявное преобразование. Int делает, но Int32 не происходит, следовательно, такое поведение:

// 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) 

Можно утверждать, что должно быть больше неявные преобразования для смазки колес, но опять же, эти неявные преобразования являются источником большого замешательства уже и направление в последней бета-версии состоит в том, чтобы иметь меньше, а не больше.

+0

благодарю вас это замечательный ответ. Вы знаете, есть ли какая-либо документация о том, какие неявные преобразования Swift делают? Я предполагаю, что это выходит за рамки просто «NSInteger». –

+0

Yup, это описано в [Использование Swift с Cocoa и Objective-C] (https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/ uid/TP40014216-CH6-XID_42) iBook. Но просто имейте в виду, что он изменился в бета-версии Xcode 6.3, и книга отражает только поведение версии релиза, поэтому лучше всего проверить примечания к выпуску Xcode при попытке обновления. –

+0

BTW Вы имеете в виду NSNumber, а не NSInteger? –

0

Протокол, который дает Int и др. Эту способность, является _ObjectiveCBridgeable, который you can adopt yourself, если вы чувствуете себя авантюрным.

+0

Это должен быть комментарий – ketan

+0

Недостаточная репутация. Кроме того, похоже, что он отвечает на вопрос «нет»? – user2488730

0

Потому что Int - значение Тип.

AnyObject относится к типов Referance типов (классов) не значение

Любой относится к типов Referance + типы значений (Структуры + классы)

Вы должны использовать любой для valueTypes, а не AnyObject

Типы значений> обычно структуры, перечисления, bla bla ..

Типы Referance> обычно классы

Есть два типа переменных> типов Referance и типов значений

типов Referance являются указателем типа и, как правило, содержат значение барана адрес, где хранятся исходные данные

Типы значений не являются адресами. Они непосредственно содержат значение переменной

Int ASD = 3 (ASD непосредственно содержит 3)

Int, Float, числовые типы, ... Дата почти всегда STRUCT (тип значения) в большинстве языков программирования.

Строка почти всегда гибрид в большинстве компьютерных языков

ViewControllers, Views, кнопки, ... массивы, словари, ... и пользовательские определенные классы Referance типы

Смежные вопросы