2016-12-16 2 views
0

Angenommen, ich entwickle eine Tweak-App, ich möchte eine Instanz einer Klasse erstellen, deren Header nicht importiert werden kann, aber ich weiß Klassenname, Klassenmethoden und Instanzmethoden Wie kann ich erstellen es in der Klassenmethode mit Parametern? Sagen Sie diese Klasse MMClass mit KlassenmethodeiOS invoke Klassenmethode mit IMP

+(instancetype)do:(NSString*)string for:(NSString *)antherString; 

Was ich tue, ist, wie unten genannt:

Class class = objc_getClass("MMClass"); 
Method initMethod = class_getClassMethod(class, 
              @selector(do:for:)); 
IMP imp = method_getImplementation(initMethod); 
id instance = imp(class,@selector(do:for:),@"do",@"ye"); 

dies richtig ist?

Antwort

0

Zuerst bin ich nicht sicher, ob ich das Offensichtliche sage, aber warum nicht einfach einen eigenen Header mit den zu verwendenden Deklarationen erstellen und diesen importieren (oder einfach die Deklaration am Anfang der Datei einfügen, wenn Sie werden es nur in einer Datei verwenden)? und die Methoden normal aufrufen? anstatt durch all diese Unordnung zu gehen? Der Compiler kümmert sich nur darum, dass eine Deklaration für die Methoden angezeigt wird, die Sie aufrufen möchten.

Wenn Sie die tatsächliche Implementierung der Methode unter Verwendung eines Funktionszeiger aufrufen, müssen Sie es auf die richtige Art von Funktionszeiger werfen auf die Unterschrift des Verfahrens entsprechen:

Class class = objc_getClass("MMClass"); 
Method initMethod = class_getClassMethod(class, @selector(do:for:)); 
IMP imp = method_getImplementation(initMethod); 
id (*foo)(Class, SEL, NSString *, NSString *) = 
    (id (*)(Class, SEL, NSString *, NSString *))imp; 
id instance = foo(class, @selector(do:for:), @"do", @"ye"); 

Aber es ist dumm ein IMP zu erhalten das wirst du nur einmal benutzen. Stattdessen sollten Sie einfach objc_msgSend an den gewünschten Funktionszeigertyp übergeben und stattdessen direkt diesen Aufruf aufrufen:

Class class = objc_getClass("MMClass"); 
id (*foo)(Class, SEL, NSString *, NSString *) = 
    (id (*)(Class, SEL, NSString *, NSString *))objc_msgSend; 
id instance = foo(class, @selector(do:for:), @"do", @"ye"); 
Class class = objc_getClass("MMClass"); 
id (*foo)(Class, SEL, NSString *, NSString *) = 
    (id (*)(Class, SEL, NSString *, NSString *))objc_msgSend; 
id instance = foo(class, @selector(do:for:), @"do", @"ye"); 
Class class = objc_getClass("MMClass"); 
id (*foo)(Class, SEL, NSString *, NSString *) = 
    (id (*)(Class, SEL, NSString *, NSString *))objc_msgSend; 
id instance = foo(class, @selector(do:for:), @"do", @"ye");