2017-02-14 1 views
1
let f:() -> Void = { } 

let array = ["a", 1, false, f] as [Any] 

if array[3] is AnyObject { 
    print(array[3]) 
} 

배열이 Any를 저장하도록 설정 되었어도 AnyObject에 대해 요소가 true로 평가되는 이유는 무엇입니까?모든 객체를 저장하는 배열도 AnyObject 유형입니다.

정의에 의한 AnyObject가 클래스 일 수는 있지만 함수가 AnyObject로서 true로 평가되는 이유는 무엇입니까? 다른 예로서

:

let f:() -> Bool = { return true } 
let ff = f as AnyObject 
(ff as() -> Bool)() 

이되었다는 내용의 API doc에 AnyObject의 정의에 반하는 :

AnyObject 어떤 인스턴스에 대한 구체적인 형태로 사용될 수있다 클래스, 클래스 유형 또는 클래스 전용 프로토콜 일 수 있습니다.

또는 공식 Swift Programming Language Guide :

모든 • 기능을 유형을 포함, 모든 모든 유형의 인스턴스를 나타낼 수 있습니다.

• AnyObject는 모든 클래스 유형의 인스턴스를 나타낼 수 있습니다.

위의 예에서 function은 AnyObject로 표현 될 수 있습니다.

SwiftValue 클래스가 사용 되었기 때문에 내부적으로 AnyObject에 브리징 할 수있는 SO의 설명이 있습니다 (@hamish가 지적한 바 있음). 설명의 논리는 구현이 부정확하거나 AnyObject 및 typecheck 연산자의 정의가 올바르지 않으므로 구현이 언어 정의에 따라야하며 그렇지 않은 경우가 아니라면 잘못되었거나 반대 일 것입니다.

+2

* 모든 것이 * 연결 가능하기 때문에 3. [AnyObject가 Xcode8 beta6에서 작동하지 않습니까?] (http://stackoverflow.com/q/39033194/2976878) – Hamish

+1

기능이 AnyObject에 연결될 수있는 이유는 무엇입니까? AnyObject의 정의를 깨뜨리지 않습니까? 가능한 경우에도이 동작은 잘못되었습니다. – Boon

+2

링크 된 Q & A를 읽으십시오 - Obj-C와 직접적으로 호환되지 않는 것들은 Objc-C 호환 상자'_SwiftValue'에 상자가 있습니다. 이것에 대한 이유는'id'가 Swift에'Any'로 연결되어 있기 때문에'Any'는'id'로 연결될 수 있어야하기 때문입니다. – Hamish

답변

1

먼저 Swift 프로그래밍 언어 가이드는 ISO 9899가 C를 정의하는 방식으로 언어 사양이 아닙니다 (ISO 표준이 주어 지더라도 모든 컴파일러가 C를 동일하게 구현하지는 않으며 표준에 따라 100 %) 컴파일러와 문서 사이에 의견 차이가 있으면 컴파일러 버그로 인한 문서 버그 일 가능성이 높습니다.

난 당신이 스펙의 중요한 부분에 호도 한 생각했다 당신은 참조 :

AnyObject 또한 Objective-에 다리 유형의 인스턴스에 대한 구체적인 유형으로 사용할 수 있습니다 C 클래스. 문자열과 Int와 같은 Objective-C의 대응 부분에 대한 스위프트 브릿지의 많은 값 유형.

() -> Void은 (dispatch/object.hos/object.h 참조) dispatch_object로 ObjC에 연결 해주는, dispatch_block_t하는 것과 같습니다

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

그래서 () -> VoidAnyObject 강요 될 수 있다는 것을 여기에 놀라운 일이 없습니다. 지금 (즉,이 구현 정확히 어떻게 아니더라도,보기, NSValueAnyObject이 될 수있을 수있는 일의 언어 사양 지점에서 다시) AnyObject으로 해소 할 수 있습니다 거의 아무것도 실제로

.

AnyObjectAny과 다릅니다. 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을 사용하는 참조 유형입니다. 그러나 이는 단지 누락 일 뿐이며 이미 존재하는 것의 모순이 아닙니다. (모순이라면 혼란 스럽거나 다시 혼란스럽게 느껴질 것입니다. 정답은 문서를 매치시키지 않고 스위프트와 일치시키기 위해 결함을 열어 보는 것입니다.)

+0

매우 통찰력있는, 롭 감사합니다! – Boon

관련 문제