我有一个数组,我正在迭代并正在寻找一个特定的标志。如果标志值为nil,则我正在调用一个方法,该方法生成一个调用对象并返回调用结果。
我的代码结构如下
for(NSString *key in [taxiPlanes allKeys])
{
Plane *currentPlane = [taxiPlanes objectForKey:key];
if(currentPlane.currentAction == nil)
{
NSString *selector = [[currentPlane planeTakeoffSequence] firstObject];
currentPlane.currentAction = selector;
// Calling for NSInvocation in [self ...]
NSArray *action = [NSArray arrayWithArray:[self operationFromTakeoffAction:currentPlane.currentAction AtPoint:currentPlane.position]];
NSLog(@"%@",action);
}
}
生成NSInvocation的方法
-(NSArray *) operationFromTakeoffAction:(NSString *) action AtPoint:(CGPoint) flightPoint
{
NSMethodSignature *methodSignature = [FlightOperations instanceMethodSignatureForSelector:NSSelectorFromString(action)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setTarget:fOps];
[invocation setSelector:NSSelectorFromString(action)];
[invocation setArgument:&flightPoint atIndex:2];
NSArray *resultSet = [NSArray alloc]init];
[invocation invoke];
[invocation getReturnValue:&resultSet];
return resultSet;
}
在for循环中,没有方法调用NSInvocation([self ....]),循环就可以很好地执行并且不会崩溃。但是,当我介绍调用NSInvocation的方法时,我能够看到用于循环的NSLog打印预期的NSArray结果,但是它崩溃并显示错误消息EXC_BAD_ACCESS。
即使NSInvocation返回正确的结果,我也无法弄清楚为什么它会失败。没有NSInvocation,for循环不会崩溃。
任何的意见都将会有帮助。
谢谢
我猜您正在使用ARC?
问题出在生产线上[invocation getReturnValue:&resultSet];
。getReturnValue:
只是将返回值的字节复制到给定的内存缓冲区中,而不管类型如何。它不知道也不关心内存管理,如果返回类型是可保留对象指针类型。由于resultSet
是__strong
对象指针类型的变量,因此ARC假定保留了已放入该变量的任何值,因此在超出范围时将释放它。在这种情况下是不正确的,因此会崩溃。(此外,您resultSet
最初指向的数组将被泄漏,因为会getReturnValue:
覆盖该值而不释放它。为什么您甚至首先将该变量指向一个对象,这也超出了我的范围。)
解决方案是,您必须为赋予非保留类型的指针getReturnValue:
。要么:
NSArray * __unsafe_unretained tempResultSet;
[invocation getReturnValue:&tempResultSet];
NSArray *resultSet = tempResultSet;
要么:
void *tempResultSet;
[invocation getReturnValue:&tempResultSet];
NSArray *resultSet = (__bridge NSArray *)tempResultSet;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句