Вы абсолютно правы, -autoContentAccessingProxy
полностью сломлен. NSAutoContentAccessingProxy
является подклассом NSProxy
и поэтому должен реализовывать методы methodSignatureForSelector:
и forwardInvocation:
или метод forwardingTargetForSelector:
, если работает на iOS 4 или более поздней версии.
Вот хардкорный способ исправления класса NSAutoContentAccessingProxy
путем добавления методов methodSignatureForSelector:
и forwardInvocation:
во время выполнения. Просто добавьте следующее в ваш проект (не компилируйте это с ARC).
#import <mach-o/dyld.h>
#import <mach-o/nlist.h>
__attribute__((constructor)) void FixAutoContentAccessingProxy(void);
static id _target(id autoContentAccessingProxy);
static NSMethodSignature *NSAutoContentAccessingProxy_methodSignatureForSelector(id self, SEL _cmd, SEL selector);
static void NSAutoContentAccessingProxy_forwardInvocation(id self, SEL _cmd, NSInvocation *invocation);
__attribute__((constructor)) void FixAutoContentAccessingProxy(void)
{
Class NSAutoContentAccessingProxy = objc_lookUpClass("NSAutoContentAccessingProxy");
Method methodSignatureForSelector = class_getInstanceMethod([NSObject class], @selector(methodSignatureForSelector:));
Method forwardInvocation = class_getInstanceMethod([NSObject class], @selector(forwardInvocation:));
class_addMethod(NSAutoContentAccessingProxy, @selector(methodSignatureForSelector:), (IMP)NSAutoContentAccessingProxy_methodSignatureForSelector, method_getTypeEncoding(methodSignatureForSelector));
class_addMethod(NSAutoContentAccessingProxy, @selector(forwardInvocation:), (IMP)NSAutoContentAccessingProxy_forwardInvocation, method_getTypeEncoding(forwardInvocation));
}
static id _target(id autoContentAccessingProxy)
{
static uint32_t targetIvarOffset;
static dispatch_once_t once;
dispatch_once(&once, ^{
struct nlist symlist[] = {{"_OBJC_IVAR_$_NSAutoContentAccessingProxy._target", 0, 0, 0, 0}, NULL};
for(uint32_t i = 0; i < _dyld_image_count(); i++)
{
if (nlist(_dyld_get_image_name(i), symlist) == 0 && symlist[0].n_value != 0)
{
uint32_t *_OBJC_IVAR_NSAutoContentAccessingProxy_target = (uint32_t*)((uint32_t)_dyld_get_image_header(i) + symlist[0].n_value);
targetIvarOffset = *_OBJC_IVAR_NSAutoContentAccessingProxy_target;
break;
}
}
});
return *(id*)((uint32_t)autoContentAccessingProxy + targetIvarOffset);
}
static NSMethodSignature *NSAutoContentAccessingProxy_methodSignatureForSelector(id self, SEL _cmd, SEL selector)
{
return [_target(self) methodSignatureForSelector:selector];
}
static void NSAutoContentAccessingProxy_forwardInvocation(id self, SEL _cmd, NSInvocation *invocation)
{
[invocation setTarget:_target(self)];
[invocation invoke];
}
Этот обходной путь следует использовать только для демонстрации нарушения NSAutoContentAccessingProxy
. В любом случае, это будет работать только на симуляторе, потому что на устройстве произойдет сбой вызова nlist
. Вы могли бы фактически заставить его работать на устройстве, используя APEFindSymbol
из APELite-arm вместо nlist
, но я не рекомендую это.
Вы обязательно должны подать отчет об ошибке об этом в Apple.