신속한 수업 소개 및 일반론
동적으로 생성하려고 합니다.class
제네릭을 사용한 인스턴스 기반 유형이지만 수업 자기소개에 어려움을 겪고 있습니다.
다음은 질문입니다.
- Obj-C와 동등한 스위프트가 있습니까?
self.class
? - 클래스를 사용하여 인스턴스화하는 방법이 있습니까?
AnyClass
으로부터 결과가 나온NSClassFromString
? - 당신이 할 수 있는 방법이 있습니까?
AnyClass
또는 일반 매개 변수의 정보를 입력합니다.T
(C#과 유사함)typeof(T)
구문)
우선 스위프트는 다음과 같은 것입니다.[NSString class]
이라.self
(메타 유형 문서를 참조하십시오. 상당히 얇습니다.)
실은.NSString.class
효과도 없어요!사용해야 합니다.NSString.self
.
let s = NSString.self
var str = s()
str = "asdf"
마찬가지로, 빠른 수업으로 시도했습니다...
class MyClass {
}
let MyClassRef = MyClass.self
// ERROR :(
let my_obj = MyClassRef()
흠… 오류는 다음과 같습니다.
Playground 실행 실패: 오류: 16:1: 오류: 메타타입 값으로 클래스 유형 'X'의 개체를 구성하려면 '@required' 이니셜라이저가 필요합니다.
Y().me() ^ <REPL>:3:7: note: selected implicit initializer with type '()' class X { ^
이것이 무엇을 의미하는지 알아내는 데 시간이 좀 걸렸습니다. 알고 보니 수업이 진행되기를 바라는 것이었습니다.@required init()
class X {
func me() {
println("asdf")
}
required init () {
}
}
let Y = X.self
// prints "asdf"
Y().me()
일부 문서에서는 이를 다음과 같이 언급합니다..Type
,그렇지만MyClass.Type
운동장에서 실수를 합니다.
사용 방법은 다음과 같습니다.NSClassFromString
당신은 당신이 무엇으로 끝날지에 대한 슈퍼클래스를 알아야 합니다.여기 슈퍼클래스-하위클래스 쌍이 있습니다. 이 쌍은 다음을 위해 자신을 설명하는 방법을 알고 있습니다.println
:
@objc(Zilk) class Zilk : NSObject {
override var description : String {return "I am a Zilk"}
}
@objc(Zork) class Zork : Zilk {
override var description : String {return "I am a Zork"}
}
특수 기능을 사용합니다.@obj
이러한 클래스의 목표-공백 이름을 지시하는 구문입니다. 그렇지 않으면 각 클래스를 지정하는 공백 문자열을 알 수 없기 때문에 중요합니다.
이제 사용할 수 있습니다.NSClassFromString
Zork 클래스 또는 Zilk 클래스를 만드는 것은 NSO 객체로 입력할 수 있고 나중에 충돌하지 않을 수 있다는 것을 알기 때문입니다.
let aClass = NSClassFromString("Zork") as NSObject.Type
let anObject = aClass()
println(anObject) // "I am a Zork"
그리고 그것은 되돌릴 수 있습니다.println(NSStringFromClass(anObject.dynamicType))
작동하기도 합니다.
최신 버전:
if let aClass = NSClassFromString("Zork") as? NSObject.Type {
let anObject = aClass.init()
print(anObject) // "I am a Zork"
print(NSStringFromClass(type(of:anObject))) // Zork
}
문서를 제대로 읽고 있다면 인스턴스를 처리하고 예를 들어 지정된 개체와 동일한 유형의 새 인스턴스를 반환하고 유형을 init()로 구성할 수 있다면 다음 작업을 수행할 수 있습니다.
let typeOfObject = aGivenObject.dynamicType
var freshInstance = typeOfObject()
String으로 빠르게 테스트했습니다.
let someType = "Fooo".dynamicType
let emptyString = someType()
let threeString = someType("Three")
그것은 잘 작동했습니다.
인스위프트 3
object.dynamicType
사용되지 않습니다.
대신 다음을 사용합니다.
type(of:object)
유형 비교의 신속한 구현
protocol Decoratable{}
class A:Decoratable{}
class B:Decoratable{}
let object:AnyObject = A()
object.dynamicType is A.Type//true
object.dynamicType is B.Type//false
object.dynamicType is Decoratable.Type//true
참고: 개체가 확장할 수도 있고 확장할 수도 없는 프로토콜과도 작동합니다.
드디어 할 일이 생겼어요.조금 게으르긴 하지만 NSClassFromString() 경로도 저에게는 통하지 않았습니다...
import Foundation
var classMap = Dictionary<String, AnyObject>()
func mapClass(name: String, constructor: AnyObject) -> ()
{
classMap[name] = constructor;
}
class Factory
{
class func create(className: String) -> AnyObject?
{
var something : AnyObject?
var template : FactoryObject? = classMap[className] as? FactoryObject
if (template)
{
let somethingElse : FactoryObject = template!.dynamicType()
return somethingElse
}
return nil
}
}
import ObjectiveC
class FactoryObject : NSObject
{
@required init() {}
//...
}
class Foo : FactoryObject
{
class override func initialize()
{
mapClass("LocalData", LocalData())
}
init () { super.init() }
}
var makeFoo : AnyObject? = Factory.create("Foo")
빙고 "make Foo"에는 Foo 인스턴스가 포함되어 있습니다.
단점은 클래스가 FactoryObject에서 파생되어야 하며 글로벌 함수 "mapClass"에 의해 클래스 맵에 자동으로 삽입되도록 Obj-C +initialize 메서드가 있어야 한다는 것입니다.
다음은 수락된 답변과 유사한 클래스 계층 구현을 보여주는 또 다른 예로, Swift의 첫 번째 릴리스에 대해 업데이트되었습니다.
class NamedItem : NSObject {
func display() {
println("display")
}
required override init() {
super.init()
println("base")
}
}
class File : NamedItem {
required init() {
super.init()
println("folder")
}
}
class Folder : NamedItem {
required init() {
super.init()
println("file")
}
}
let y = Folder.self
y().display()
let z = File.self
z().display()
다음 결과를 인쇄합니다.
base
file
display
base
folder
display
언급URL : https://stackoverflow.com/questions/24049673/swift-class-introspection-generics
'programing' 카테고리의 다른 글
pyenv 가상 환경에서 실행되는 Python 스크립트에 사용할 shebang (0) | 2023.08.10 |
---|---|
IO 타이밍 측정으로 L1 캐시 라인 크기를 찾는 방법은 무엇입니까? (0) | 2023.08.10 |
Python에는 스택/히프가 있으며 메모리는 어떻게 관리됩니까? (0) | 2023.08.10 |
문자열 데이터에 putExtra() 및 getExtra()를 사용하는 방법 (0) | 2023.08.10 |
기본 키를 덤프하지 않는 mysqdump 테이블 (0) | 2023.08.10 |