2015-02-13 1 views
2

У нас есть следующий метод, который работает для объектов. Он принимает метод объекта и помещает результат в returnValueContainer:NSInvocation с примитивным использованием getReturnValue

+ (void)invokePrivateMethod:(SEL)selector returnValueContainer:(NSObject **)returnValueContainer onObject:(NSObject *)object { 
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[object class] instanceMethodSignatureForSelector:selector]]; 
    [invocation setSelector:selector]; 
    [invocation setTarget:object]; 
    [invocation invoke]; 
    [invocation getReturnValue:returnValueContainer]; 
} 

Можно ли изменить это как-то так, что мы можем вернуться примитивов (например, NSInteger), а также объекты из getReturnValue?

Фон: мы пытаемся получить доступ к частному примитивному свойству класса для модульных тестов.

ответ

3

Ну, если вы хотите сделать это с помощью int, этого достаточно просто изменить его на returnValueContainer:(int *)returnValueContainer. Если вы хотите, чтобы он работал на всех типах, вы можете просто сделать returnValueContainer:(void *)returnValueContainer и позволить вызывающему абоненту передать указатель на нужный тип.

(Кстати, то, что вы делаете с NSObject ** не является правильным в АРК. Параметр типа NSObject ** неявно означает NSObject * __autoreleasing *. Но правильный тип должен быть NSObject * __unsafe_unretained *, потому что getReturnValue: просто обрабатывает буфер, указанный как простой буфер байтов не зная ничего об управлении памятью, он не сохраняет и не автореклассирует его так, как должен, для типа __autorelease. В большинстве случаев это не будет иметь никакого значения (и метод, который был вызван, возможно, автореализовал его в любом случае), бывают случаи, когда он будет иметь значение.)

+0

Блестящий. Спасибо. –