Во-первых, руководство по языку программирования Swift не является спецификацией языка в том смысле, в каком ISO 9899 определяет C. (И даже при наличии стандарта ISO не каждый компилятор реализует C идентично или даже в 100% соответствии со стандартом.) Если вы найти несоответствие между компилятором и документацией, скорее всего, это ошибка документации, как и ошибка компилятора.
Тем не менее, я считаю, что вы упустили из виду важную часть спецификации, на которую вы ссылаетесь:
AnyObject также можно использовать в качестве конкретного типа для экземпляра типа, который связывается с классом Objective-C. Многие типы значений в Swift соединяются с аналогами Objective-C, такими как String и Int.
() -> Void
эквивалентен dispatch_block_t
, который соединяется с ObjC как dispatch_object
(см. dispatch/object.h
и os/object.h
):
/*
* By default, dispatch objects are declared as Objective-C types when building
* with an Objective-C compiler. This allows them to participate in ARC, in RR
* management by the Blocks runtime and in leaks checking by the static
* analyzer, and enables them to be added to Cocoa collections.
* See <os/object.h> for details.
*/
OS_OBJECT_DECL_CLASS(dispatch_object);
Так что нет ничего удивительного в том, что () -> Void
можно превратить в AnyObject
.
На практике практически все теперь может соединяться с AnyObject
(опять же, с точки зрения спецификации языка, все, что может быть NSValue
, может быть AnyObject
, хотя это не совсем так, как это реализовано).
Однако AnyObject
отличается от Any
. Any
ведет себя как протокол (несмотря на то, что это не протокол). AnyObject
ведет себя как суперкласс любого класса (несмотря на то, что на самом деле это протокол).
let b = true // true
let bany = true as Any // true
let banyobj = true as AnyObject // 1 <=== (because it's NSNumber)
MemoryLayout.size(ofValue: b) // 1 (size of a bool)
MemoryLayout.size(ofValue: bany) // 32 (size of a protocol box)
MemoryLayout.size(ofValue: banyobj) // 8 (size of a reference pointer)
type(of: b) // Bool.Type
type(of: bany) // Bool.Type
type(of: banyobj) // __NSCFBoolean.Type
(Попробуйте то же самое для {}
, чтобы увидеть, как обрабатываются замыкания.)
Разумно открыть дефект в документах AnyObject
, чтобы включить более подробное объяснение того, что любой тип может быть преобразован в ссылочный тип с помощью as AnyObject
, но это просто упущение, а не противоречие тому, что уже есть. (И если это противоречие или вы находите это запутанным, опять же, правильный ответ — открыть дефект, чтобы улучшить документы, чтобы они соответствовали Swift, а не Swift, чтобы они соответствовали документам.)
person
Rob Napier
schedule
15.02.2017
AnyObject
в Swift 3. См. AnyObject не работает в Xcode8 beta6? - person Hamish   schedule 14.02.2017_SwiftValue
. Причина этого в том, чтоid
теперь подключен к Swift какAny
, поэтомуAny
необходимо подключить обратно кid
. - person Hamish   schedule 15.02.2017_SwiftValue
— это класс (должен быть, чтобы быть совместимым с Obj-C), и, следовательно, являетсяAnyObject
. - person Hamish   schedule 15.02.2017Any
иAnyObject
. Если вы широко используете эти типы, вы либо работаете с Cocoa (что является временной и улучшающейся ситуацией), либо, вероятно, делаете что-то не так. В Swift следует избегать таких типов, как[Any]
. Но когда приходится иметь дело с Cocoa, имеет смысл сделать его максимально удобным и прозрачным (мостовым). - person Rob Napier   schedule 15.02.2017Foundation
, правильно? Это изменяет поведениеAnyObject
. Я не говорю, что это задокументировано, я говорю, чтоAnyObject
— это глубокая трясина безумия, которую, если она вам не нужна для соединения с Cocoa, вам, вероятно, не следует использовать в любом случае, и, вероятно, в будущем она изменится каким-то странным образом. иногда какая-то функция делает переход к Cocoa более полезным. Я не защищаю Swift в этом, как это обычно бывает. - person Rob Napier   schedule 15.02.2017