Ошибка компиляции с ARC при динамическом программировании во время выполнения

Я пытаюсь сделать некоторое программирование во время выполнения на Objective-C. Для этого я перезаписываюresolveClassMethod метод.

К сожалению, я обнаружил ошибку при компиляции clang, когда ARC активен:

ошибка: неизвестный метод класса для селектора 'dynamic'

Все работает нормально, если я использую gcc или clang без ARC (-fno-ObjC-дуга опция пройдена), кроме предупреждения вместо ошибки.

Мне известно, что ARC нужно знать имя вызываемого метода, чтобы выяснить, как управлять памятью с возвращаемым значением (следуя соглашению имен методов). Но как решить эту проблему без уродливойperformSelector вызов вместо прямого вызова метода?

Вот мой код:

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 или лязг без ARC

Результат компиляции

main.m: 13: 36: предупреждение: метод класса '+ dynamic' не найден (тип возвращаемого значения по умолчанию равен 'id')

    NSLog(@"How are you , %@", [Test dynamic]);

Выход

2012-10-22 10: 33: 15.563 test-clang [957: 707] Привет, Джон 2012-10-22

2012-10-22 10: 33: 15.565 test-clang [957: 707] Динамический метод, называемый 2012-10-22

2012-10-22 10: 33: 15.565 test-clang [957: 707] Как дела, dynamicImp

Лязг с дугой

Результат компиляции

main.m: 13: 36: ошибка: неизвестный метод класса для селектора 'dynamic'

    NSLog(@"How are you , %@", [Test dynamic]);

PS: мне сейчас наплевать на управление памятью, так как моя цель - скомпилировать этот код с активированной ARC.

Ответы на вопрос(2)

Ваш ответ на вопрос