Błąd podczas kompilacji za pomocą ARC podczas dynamicznej metody programowania w czasie wykonywania
Próbuję wykonać pewne programowanie środowiska wykonawczego w Objective-C. W tym celu zastępujęresolveClassMethod metoda.
Niestety pojawia się błąd kompilacji z clang, gdy ARC jest aktywne:
błąd: brak znanej metody klasy dla „dynamicznego” selektora
Wszystko działa dobrze, jeśli używam gcc lub clang bez ARC (-fno-objc-arc przekazana opcja), z wyjątkiem ostrzeżenia zamiast błędu.
Zdaję sobie sprawę, że ARC musi znać nazwę wywołanej metody, aby dowiedzieć się, jak zarządzać pamięcią o zwróconej wartości (zgodnie z konwencją nazwy metody). Ale jak do tego problemu bez brzydkiegoperformSelector zadzwonić zamiast bezpośredniego wywołania metody?
Oto mój kod:
Test.m
#import "Test.h"
#import <objc/runtime.h>
NSString* dynamicImp(id slef, SEL _cmd)
{
NSLog(@"Dynamic method called");
return @"dynamicImp";
}
@implementation Test
- (NSString*)name
{
return @"John";
}
+ (BOOL)resolveClassMethod:(SEL)name
{
if (name == @selector(dynamic))
{
Class metaClass = objc_getMetaClass([NSStringFromClass([self class]) UTF8String]);
class_addMethod(metaClass, name, (IMP) dynamicImp, "@@:");
return YES;
}
return NO;
}
+ (IMP)methodForSelector:(SEL)aSelector
{
if (aSelector == @selector(dynamic))
{
return (IMP) dynamicImp;
}
else
{
return [super methodForSelector:aSelector];
}
}
- (BOOL)respondsToSelector:(SEL)aSelector
{
if (aSelector == @selector(dynamic))
{
return YES;
}
else
{
return [NSObject respondsToSelector:aSelector];
}
}
@end
Test.h
#import <Cocoa/Cocoa.h>
@interface Test : NSObject <NSObject> {
NSString *_name;
}
- (NSString*)name;
@end
main.m
#import <Cocoa/Cocoa.h>
#import <stdio.h>
#import "Test.h"
int main(int argc, char* argv[])
{
@autoreleasepool {
Test *test = [[Test alloc] init];
NSLog(@"Hello, %@", [test name]);
NSLog(@"How are you , %@", [Test dynamic]);
}
return 0;
}
Gcc lub clang bez ARC
Wynik kompilacji
main.m: 13: 36: warning: nie znaleziono metody klasy „+ dynamiczne” (typ powrotu domyślnie to „id”)
NSLog(@"How are you , %@", [Test dynamic]);
Wydajność
2012-10-22 10: 33: 15.563 test-brzęk [957: 707] Hello, John 2012-10-22
2012-10-22 10: 33: 15.565 test-clang [957: 707] Metoda dynamiczna o nazwie 2012-10-22
2012-10-22 10: 33: 15.565 test-clang [957: 707] Jak się masz, dynamicImp
Clang z ARC
Wynik kompilacji
main.m: 13: 36: error: brak znanej metody klasy dla dynamicznego selektora
NSLog(@"How are you , %@", [Test dynamic]);
PS: Na razie nie dbałem o zarządzanie pamięcią, ponieważ moim celem jest skompilowanie tego kodu z aktywowanym ARC.