[ios] 스위프트 언어 NSClassFromString

스위프트 언어로 반영 하는 방법은 무엇입니까?

클래스를 인스턴스화하는 방법

[[NSClassFromString(@"Foo") alloc] init];



답변

덜 해키 솔루션 : https://stackoverflow.com/a/32265287/308315

Swift 클래스는 이제 네임 스페이스가 지정되므로 “MyViewController”대신 “AppName.MyViewController”가됩니다.


XCode6-beta 6/7부터 사용되지 않음

XCode6-beta 3을 사용하여 개발 된 솔루션

Edwin Vermeer의 답변 덕분에 다음과 같이 Swift 클래스를 Obj-C 클래스로 인스턴스화하는 무언가를 만들 수있었습니다.

// swift file
// extend the NSObject class
extension NSObject {
    // create a static method to get a swift class for a string name
    class func swiftClassFromString(className: String) -> AnyClass! {
        // get the project name
        if  var appName: String? = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleName") as String? {
            // generate the full name of your class (take a look into your "YourProject-swift.h" file)
            let classStringName = "_TtC\(appName!.utf16count)\(appName)\(countElements(className))\(className)"
            // return the class!
            return NSClassFromString(classStringName)
        }
        return nil;
    }
}

// obj-c file
#import "YourProject-Swift.h"

- (void)aMethod {
    Class class = NSClassFromString(key);
    if (!class)
        class = [NSObject swiftClassFromString:(key)];
    // do something with the class
}

편집하다

순수 obj-c에서도 수행 할 수 있습니다.

- (Class)swiftClassFromString:(NSString *)className {
    NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
    NSString *classStringName = [NSString stringWithFormat:@"_TtC%d%@%d%@", appName.length, appName, className.length, className];
    return NSClassFromString(classStringName);
}

나는 이것이 누군가를 도울 수 있기를 바랍니다!


답변

당신은 @objc(SwiftClassName)당신의 신속한 클래스 위에 두어야합니다 .
처럼:

@objc(SubClass)
class SubClass: SuperClass {...}


답변

이것은 클래스 이름으로 파생 된 UIViewController를 초기화하는 방법입니다.

var className = "YourAppName.TestViewController"
let aClass = NSClassFromString(className) as! UIViewController.Type
let viewController = aClass()

자세한 정보는 여기

iOS 9에서

var className = "YourAppName.TestViewController"
let aClass = NSClassFromString(className) as! UIViewController.Type
let viewController = aClass.init()


답변

업데이트 : 베타 6부터 NSStringFromClass는 번들 이름과 점으로 구분 된 클래스 이름을 반환합니다. 따라서 MyApp.MyClass와 같은 것입니다.

Swift 클래스는 다음 부분으로 구성된 구성된 내부 이름을 갖습니다.

  • _TtC로 시작합니다.
  • 애플리케이션 이름의 길이에 해당하는 숫자
  • 애플리케이션 이름,
  • 클래스 이름의 길이에 해당하는 숫자가 표시됩니다.
  • 수업 이름이 이어집니다.

따라서 클래스 이름은 _TtC5MyApp7MyClass와 같습니다.

다음을 실행하여이 이름을 문자열로 가져올 수 있습니다.

var classString = NSStringFromClass(self.dynamicType)

업데이트 Swift 3에서는 다음과 같이 변경되었습니다.

var classString = NSStringFromClass(type(of: self))

해당 문자열을 사용하여 다음을 실행하여 Swift 클래스의 인스턴스를 만들 수 있습니다.

var anyobjectype : AnyObject.Type = NSClassFromString(classString)
var nsobjectype : NSObject.Type = anyobjectype as NSObject.Type
var rec: AnyObject = nsobjectype()


답변

거의 똑같아

func NSClassFromString(_ aClassName: String!) -> AnyClass!

이 문서를 확인하십시오.

https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/#//apple_ref/c/func/NSClassFromString


답변

객체를 동적으로 인스턴스화 할 수있었습니다.

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

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

나는 (Obj-C를 사용하지 않고) AnyClass에서 만드는 방법을 찾지 못했습니다 String. 나는 기본적으로 유형 시스템을 깨뜨리기 때문에 당신이 그렇게하는 것을 원하지 않는다고 생각합니다.


답변

swift2의 경우이 작업을 더 빠르게 수행하기 위해 매우 간단한 확장을 만들었습니다.
https://github.com/damienromito/NSObject-FromClassName

extension NSObject {
    class func fromClassName(className : String) -> NSObject {
        let className = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String + "." + className
        let aClass = NSClassFromString(className) as! UIViewController.Type
        return aClass.init()
    }
}

제 경우에는 원하는 ViewController를로드하기 위해 이렇게합니다.

override func viewDidLoad() {
    super.viewDidLoad()
    let controllers = ["SettingsViewController", "ProfileViewController", "PlayerViewController"]
    self.presentController(controllers.firstObject as! String)

}

func presentController(controllerName : String){
    let nav = UINavigationController(rootViewController: NSObject.fromClassName(controllerName) as! UIViewController )
    nav.navigationBar.translucent = false
    self.navigationController?.presentViewController(nav, animated: true, completion: nil)
}