source

Swift는 reflection을 지원합니까?

factcode 2023. 9. 11. 22:16
반응형

Swift는 reflection을 지원합니까?

스위프트는 반성을 지지합니까? 예를 들어 다음과 같은 것이 있습니까?valueForKeyPath:그리고.setValue:forKeyPath:스위프트 물체에?

사실 동적 유형의 시스템을 가지고 있나요?obj.class목표-C에서?

몇 가지 반사 지원이 시작된 것 같습니다.

class Fruit {
    var name="Apple"
}

reflect(Fruit()).count         // 1
reflect(Fruit())[0].0          // "name"
reflect(Fruit())[0].1.summary  // "Apple"

mchamber gist에서 여기: https://gist.github.com/mchambers/fb9da554898dae3e54f2

클래스가 확장되는 경우NSObject, 그러면 Objective-C의 모든 내성과 역동성이 작동합니다.여기에는 다음이 포함됩니다.

  • 클래스에 메서드 및 속성에 대해 묻고 메서드를 호출하거나 속성을 설정하는 기능입니다.
  • 메소드 구현을 교환하는 기능.(모든 인스턴스에 기능 추가).
  • 새 하위 클래스를 즉시 생성하고 할당하는 기능. (특정 인스턴스에 기능 추가)

이 기능의 단점 중 하나는 Swift 옵션 값 유형을 지원한다는 것입니다.예를 들어 Int 속성을 열거하고 수정할 수 있지만 Int? 속성은 수정할 수 없습니다.옵션 유형은 reflect/MirrorType을 사용하여 부분적으로 열거할 수 있지만 여전히 수정되지는 않습니다.

클래스가 확장되지 않는 경우NSObject, 그러면 매우 제한적인(그리고 진행 중인?) 새로운 리플렉션만 작동합니다(reflect/MirrorType 참조). 여기에는 인스턴스의 클래스와 속성에 대해 묻는 기능이 제한적으로 추가되지만 위의 추가 기능은 없습니다.

NSObject를 확장하지 않거나 '@objc' 지시어를 사용하는 경우 Swift는 기본적으로 정적 및 vtable 기반 디스패치로 설정됩니다.그러나 가상 시스템이 없는 경우에는 런타임 메소드 가로채기가 허용되지 않는 경우가 더 빠릅니다.이 가로채기는 코코아의 기본적인 부분이며 다음과 같은 유형의 기능에 필요합니다.

  • 코코아의 우아한 부동산 관찰자들. (부동산 관찰자들은 스위프트 언어로 바로 구워졌습니다.)
  • 로깅, 트랜잭션 관리(즉, Aspect Oriented Programming)와 같은 교차 절단 문제를 비침습적으로 적용합니다.
  • 프록시, 메시지 전달 등

따라서 Swift를 사용하여 구현된 Cocoa/CocoaTouch 애플리케이션에서 클래스를 분류하는 것이 좋습니다.

  • NSObject에서 확장합니다.Xcode의 새 클래스 대화상자는 이 방향으로 향합니다.
  • 동적 디스패치의 오버헤드로 인해 성능 문제가 발생하는 경우 정적 디스패치를 사용할 수 있습니다. 예를 들어, 매우 작은 본체를 가진 메소드에 대한 호출과 함께 긴밀한 루프를 형성합니다.

요약:.

  • 스위프트는 빠른 정적/vtable 디스패치와 제한된 반사를 통해 C++처럼 행동할 수 있습니다.따라서 낮은 레벨 또는 성능 집약적인 애플리케이션에는 적합하지만 C++와 관련된 복잡성, 학습 곡선 또는 오류 위험이 없습니다.
  • 스위프트가 컴파일된 언어인 반면, 메소드 호출의 메시징 스타일은 Objective-C와 마찬가지로 루비나 파이썬과 같은 현대 언어에서 볼 수 있는 내성과 역동성을 추가하지만 Objective-C의 레거시 구문은 포함하지 않습니다.

참조 데이터:메서드 호출에 대한 실행 오버헤드:

  • 정적 : < 1.1ns
  • vtable : ~ 1.1ns
  • 동적 : ~4.9ns

(성능은 하드웨어에 따라 다르지만 비율은 유사하게 유지됩니다.)

또한 동적 속성을 사용하면 방법이 동적 디스패치를 사용해야 한다고 Swift에 명시적으로 지시할 수 있으므로 가로채기를 지원합니다.

public dynamic func foobar() -> AnyObject {
}

이 문서는 동적 유형 시스템에 대해 말하고 있으며, 주로 다음에 대해 설명합니다.

Type그리고.dynamicType

메타유형 유형 참조(언어 참조)

예:

var clazz = TestObject.self
var instance: TestObject = clazz()

var type = instance.dynamicType

println("Type: \(type)") //Unfortunately this prints only "Type: Metatype"

를 가정합니다.TestObjectNSObject

var clazz: NSObject.Type = TestObject.self
var instance : NSObject = clazz()

if let testObject = instance as? TestObject {
    println("yes!") //prints "yes!"
}

현재는 반영이 이루어지지 않고 있습니다.

편집: 제가 분명히 틀렸습니다. 스티브엑스의 대답을 보세요.IDE가 개체 내용을 검사할 수 있도록 내장된 속성에 대한 간단한 읽기 전용 반사 기능이 있습니다.

아니요.reflect5의 는 이제 swift 5의 키워드를 할 수 .

struct Person {
    var name="name"
    var age = 15
}

var me = Person()
var mirror = Mirror(reflecting: me)

for case let (label?, value) in mirror.children {
    print (label, value)
}

현재로서는 스위프트 리플렉션 API가 애플의 높은 우선순위는 아닌 것 같습니다.그러나 @stevex answer 이외에도 표준 라이브러리에 도움이 되는 또 다른 기능이 있습니다.

6 ≥ 6 ≥ 6 ≥ 6 _stdlib_getTypeName변수의 망글 형식 이름을 가져옵니다.:에기빈기:

import Foundation

class PureSwiftClass {
}

var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"

println( "TypeName0 = \(_stdlib_getTypeName(myvar0))")
println( "TypeName1 = \(_stdlib_getTypeName(myvar1))")
println( "TypeName2 = \(_stdlib_getTypeName(myvar2))")
println( "TypeName3 = \(_stdlib_getTypeName(myvar3))")

출력은 다음과 같습니다.

TypeName0 = NSString
TypeName1 = _TtC13__lldb_expr_014PureSwiftClass
TypeName2 = _TtSi
TypeName3 = _TtSS

Ewan Swick의 블로그 항목은 다음 문자열을 해독하는 데 도움이 됩니다.

를 들면 _TtSi스위프트의t의 입니다.Inttype .type .

Mike Ash는 같은 주제를 다루는 훌륭한 블로그 엔트리를 가지고 있습니다.

대신 toString()을 사용하는 것을 고려해 볼 수 있습니다.공개되며 _stdlib_get과 동일하게 작동합니다.Playground Enter와 같은 AnyClass에서도 작동한다는 차이점이 있는 Name()입력합니다.

class MyClass {}

toString(MyClass.self) // evaluates to "__lldb_expr_49.MyClass"

언급URL : https://stackoverflow.com/questions/24060667/does-swift-support-reflection

반응형