2017-01-23 3 views
2

Ich versuche dynamisch eine Swift-Klasse zu laden, die von NSObject mit der Objc-Laufzeit erbt. (Ich versuche, die Klasse von ObjC, nicht von Swift zu laden)objc_getClass: load Swift-Klasse erbt NSObject

Meine Swift-Klasse: Die

@objc public class TestClass : NSObject { 

    @objc public func testMethod() -> String { 
     return "String" 
    } 

} 

Laut Apple Dokumentation,

Das @objc Attribut macht Swift API verfügbar in Objective-C und Objective-C-Laufzeit

Aber das Ergebnis von objc_getClass("TestClass") ist (null).

Mache ich etwas falsch? Oder ist es überhaupt nicht möglich, Swift-Klassen zu laden, die eine ObjC-Klasse mit der Objc-Laufzeit erben?

Antwort

3

Sie benötigen verwendet wird, um eine Objective-C Namen für die Klasse angeben, nicht enthalten nur @objc:

@objc(TestClass) public class TestClass : NSObject { 

    @objc public func testMethod() -> String { 
     return "String" 
    } 

} 

NSClassFromString("TestClass") // TestClass.Type 

objc_getClass("TestClass") // TestClass 

Andernfalls Ihre Klasse wird nicht registriert mit der Objective-C-Laufzeit und Anrufe wie objc_getClass oder NSClassFromString werden nil zurückgeben.

+1

Wenn Sie 'print (TestClass.className())' (ohne Angabe eines Objective-C-Namens) ausführen, wird "objc_class_name.TestClass" ausgegeben, was Sie mit 'objc_getClass' verwenden können. Es ist also mit der Laufzeit registriert, es hat nur einen vorangestellten Namen. – Hamish

+0

@Hamish ooh Ich wusste das nicht. Vielen Dank! Ich werde meine Antwort bearbeiten. – JAL

+0

@Hamish Hmm, 'TestClass.className()' kompiliert nicht für mich (Swift 3). – JAL

2

Was ist, wenn Sie versuchen objc_getClass("YourAppName.TestClass")? Wahrscheinlich wird der Modulname vorangestellt. Sie können den genauen Namen überprüfen, die hinter den Kulissen unter Verwendung NSStringFromClass([TestClass class])

+3

Eine Namespace-Kollision ist nicht das Problem in diesem speziellen Fall, aber gute Vermutung. – JAL