【发布时间】:2015-02-26 18:22:12
【问题描述】:
我已经开始准备一个支持 arm64 架构的旧项目。但是当我尝试在 64 位设备上执行此代码时,我在 [invocation retainArguments] 上遇到 EXC_BAD_ACCESS 崩溃;线
- (void)makeObjectsPerformSelector: (SEL)selector withArguments: (void*)arg1, ...
{
va_list argList;
NSArray* currObjects = [NSArray arrayWithArray: self];
for (id object in currObjects)
{
if ([object respondsToSelector: selector])
{
NSMethodSignature* signature = [[object class] instanceMethodSignatureForSelector: selector];
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature];
invocation.selector = selector;
invocation.target = object;
if (arg1 != nil)
{
va_start(argList, arg1);
char* arg = arg1;
for (int i = 2; i < signature.numberOfArguments; i++)
{
const char* type = [signature getArgumentTypeAtIndex: i];
NSUInteger size, align;
NSGetSizeAndAlignment(type, &size, &align);
NSUInteger mod = (NSUInteger) arg % align;
if (mod != 0)
arg += (align - mod);
[invocation setArgument: arg
atIndex: i];
arg = (i == 2) ? (char*) argList : (arg + size);
}
va_end(argList);
}
[invocation retainArguments];
[invocation invoke];
}
}
}
看来参数有问题。
【问题讨论】:
-
您能否提供调用该代码并崩溃的代码示例?
-
给定的代码是 NSArray 类的一个类别,为数组中的每个对象提供了使用多个参数执行选择器的能力。数组中的每个对象 - 都是一个侦听器(委托),正如“多个侦听器”设计模式所要求的那样。例如 - 在服务器响应后,我们应该让每个监听器执行选择器。调用位于服务器成功回调中,看起来像 -
[self.listeners makeObjectsPerformSelector: @selector(serverManager:didLikeVideo:withError:) withArguments: self, operation.video, operation.error, nil]; -
所以,没有不安全的类型转换,请查看我更新的答案。无法理解你为什么要在内存中定位参数来使用复杂的技巧
标签: ios nsinvocation arm64