Swift로 몇 가지 isa를 테스트 한 결과 NSObject가 수퍼 클래스 (직접 또는 더 높은 수준)이거나 ‘@objc’장식을 사용하는 경우에만 작동한다는 것을 발견했습니다. 그렇지 않으면 C ++와 같은 static- 및 vtable-dispatch 스타일을 따릅니다.
Cocoa / NSObject 기본 클래스없이 Swift 클래스를 정의하는 것이 정상입니까? 내가 염려된다면 이것은 메소드 인터 셉션 및 런타임 인트로 스펙 션과 같은 Objective-C의 역 동성을 훨씬 앞선 것을 의미합니다.
동적 런타임 동작은 속성 관찰자, 핵심 데이터, 측면 지향 프로그래밍 , 고차원 메시징 , 분석 및 로깅 프레임 워크 등과 같은 기능의 핵심 입니다.
Objective-C의 메서드 호출 스타일을 사용하면 메서드 호출에 약 20 개의 기계 코드 피연산자가 추가되므로 특정 상황에서 ( 작은 본문이있는 메서드에 대한 많은 엄격한 호출 ) C ++ 스타일 정적 및 vtable 디스패치가 더 잘 수행 될 수 있습니다.
그러나 일반적인 95-5 규칙 ( 95 %의 성능 향상은 코드의 5 % 조정에서 비롯됨)을 고려할 때 강력한 동적 기능으로 시작하여 필요한 경우 강화하는 것이 합리적이지 않습니까?
답변
NSObject의 하위 클래스 인 Swift 클래스 :
- Objective-C 클래스 자체입니다.
objc_msgSend()
(대부분의) 메서드 호출에 사용- 메서드 구현 (대부분)에 대한 Objective-C 런타임 메타 데이터 제공
NSObject의 하위 클래스가 아닌 Swift 클래스 :
- Objective-C 클래스이지만 NSObject 호환성을 위해 몇 가지 메소드 만 구현합니다.
objc_msgSend()
메서드 호출에 사용하지 마십시오 (기본값).- 메서드 구현에 대한 Objective-C 런타임 메타 데이터를 제공하지 않습니다 (기본값).
Swift에서 NSObject를 서브 클래 싱하면 Objective-C 런타임 유연성은 물론 Objective-C 성능도 얻을 수 있습니다. Objective-C의 유연성이 필요하지 않은 경우 NSObject를 피하면 성능이 향상 될 수 있습니다.
편집하다:
Xcode 6 베타 6에서는 동적 속성이 나타납니다. 이를 통해 메서드가 동적 디스패치를 사용해야하며 따라서 가로 채기를 지원하도록 Swift에 지시 할 수 있습니다.
public dynamic func foobar() -> AnyObject {
}
답변
또한 NSObject에 Swift 클래스를 기반으로하면 코딩 버그를 숨길 수있는 예기치 않은 런타임 동작을 발견했습니다. 여기에 예가 있습니다.
NSObject를 기반으로 하지 않는 이 예제 에서 컴파일러는 testIncorrect_CompilerShouldSpot에서 오류를 올바르게 발견하여 “… ‘MyClass’는 ‘MirrorDisposition’으로 변환 할 수 없습니다.”라고보고합니다.
class MyClass {
let mString = "Test"
func getAsString() -> String {
return mString
}
func testIncorrect_CompilerShouldSpot() {
var myString = "Compare to me"
var myObject = MyClass()
if (myObject == myString) {
// Do something
}
}
func testCorrect_CorrectlyWritten() {
var myString = "Compare to me"
var myObject = MyClass()
if (myObject.getAsString() == myString) {
// Do something
}
}
}
NSObject를 기반으로하는이 예제 에서 컴파일러 는 testIncorrect_CompilerShouldSpot에서 오류를 발견 하지 않습니다 .
class myClass : NSObject {
let mString = "Test"
func getAsString() -> String {
return mString
}
func testIncorrect_CompilerShouldSpot() {
var myString = "Compare to me"
var myObject = MyClass()
if (myObject == myString) {
// Do something
}
}
func testCorrect_CorrectlyWritten() {
var myString = "Compare to me"
var myObject = MyClass()
if (myObject.getAsString() == myString) {
// Do something
}
}
}
도덕적 인 것은 당신이 정말로 해야하는 NSObject에만 기반한다는 것입니다!
답변
언어 참조에 따르면 클래스가 표준 루트 클래스를 하위 클래스로 분류하기위한 요구 사항이 없으므로 필요에 따라 수퍼 클래스를 포함하거나 생략 할 수 있습니다.
클래스 선언에서 슈퍼 클래스를 생략해도 어떤 종류의 암시 적 기본 슈퍼 클래스도 할당되지 않습니다. 독립적 인 클래스 계층 구조의 루트가되는 기본 클래스를 정의합니다.
언어 참조에서 :
Swift 클래스는 범용 기본 클래스에서 상속되지 않습니다. 수퍼 클래스를 지정하지 않고 정의한 클래스는 자동으로 빌드 할 기본 클래스가됩니다.
super
수퍼 클래스가없는 클래스 (즉, 기본 클래스)에서 참조하려고 하면 컴파일 시간 오류가 발생합니다.
'super' members cannot be referenced in a root class
답변
저는 스위프트 데이터의 대부분이 objc
. Objective C 인프라와 통신해야하는 부분 만 명시 적으로 표시됩니다.
런타임 인트로 스펙 션이 언어에 어느 정도 추가 될지는 모르겠습니다. 메서드 차단은 메서드가 명시 적으로 허용하는 경우에만 가능합니다. 이것은 내 생각이지만, 애플 내의 언어 디자이너들만이 그들이 정말로 어디로 가고 있는지 정말로 알고 있습니다.
답변
다음은 Apple의 Swift-eBook에서 복사되었으며 질문에 대한 적절한 답변을 제공합니다.
기본 클래스 정의
다른 클래스에서 상속하지 않는 모든 클래스를 기본 클래스라고합니다.
Swift 클래스는 범용 기본 클래스에서 상속되지 않습니다. 수퍼 클래스를 지정하지 않고 정의한 클래스는 자동으로 빌드 할 기본 클래스가됩니다.
참고
답변
보통이다. Swift의 디자인 목표를보십시오. 목표는 방대한 종류의 프로그래밍 문제를 없애는 것입니다. 메소드 재구성은 아마도 스위프트로하고 싶은 일 중 하나가 아닐 것입니다.