我正在尝试创建NSInvocationOperation,以便它应该使用params调用object的方法
- (void) getImages: (NSRange) bounds
{
NSOperationQueue *queue = [NSOperationQueue new];
NSArray * params = [NSArray arrayWithObjects:
[[NSNumber alloc] initWithInt: bounds.location],
[[NSNumber alloc] initWithInt: bounds.length]];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(loadImagesWithOperation)
object:params];
[queue addOperation:operation];
[operation release];
}
- (void) loadImagesWithOperation:(NSArray*)bounds {
NSLog(@"loadImagesWithOperation");
}
此代码与EXC_BAD_ACCESS崩溃。如果我改变要调用的函数的定义
- (void) loadImagesWithOperation {
NSLog(@"loadImagesWithOperation");
}
一切都变好了。我试图在 @selector 的代码块中使用不同的语法,如 @selector(loadImagesWithOperation :) 和 @selector(loadImagesWithOperation:bounds :) ,但没有成功。
用params定义选择器和函数的正确方法是什么?
感谢。
答案 0 :(得分:5)
定义带参数的SEL
的正确方法是为每个参数使用冒号(":"
)字符,因此在您的情况下,选择器将如下所示:
@selector(loadImagesWithOperation:)
因此,您的NSInvocationOperation
对象应该像这样初始化:
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(loadImagesWithOperation:)
object:params];
哦,就像旁注一样,NSArray
中getImages:
的初始化存在内存泄漏:
NSArray * params = [NSArray arrayWithObjects:
[[NSNumber alloc] initWithInt: bounds.location],
[[NSNumber alloc] initWithInt: bounds.length]];
这会添加已retainCount
1
+alloc
的对象,因为您使用的是NSArray
,因此当它们添加到-retain
时,会发送{ {1}}消息,从而将retainCount
增加到2
。
取消分配此NSArray
后,这些对象将不会被取消分配,因为他们的retainCount
将是1
,而不是0
。
这个问题有三种解决方案:
autorelease
消息添加到NSArray
之前,将NSNumber
消息发送给每个对象。numberWithInt:
的{{1}}类方法获取自动释放的NSNumber
对象。NSNumber
个对象的引用,将其添加到NSArray
,然后添加后,向其发送-release
消息。答案 1 :(得分:3)
一切都变好了。我试过了 在@ selector中使用不同的语法 代码块就好 @选择(loadImagesWithOperation :) 和 @selector(loadImagesWithOperation:边界:) 但没有成功。
initWithTarget:selector:object:
采用一个可以接受0或1个参数的选择器,不再是(不是2个)。那一个论点必须是一个对象。如果你需要更多的参数,可以使用块或重构你的代码(传递一个包含其余对象的数组是一个潜在的解决方案,是的 - 有点像你在那段代码中所做的那样(尽管注意内存泄漏)。 / p>
崩溃与您显示的代码无关。发布崩溃。
另请注意,在头部具有get
的方法在Cocoa / iOS中具有非常特定的含义,并且不用于此类模式。我建议loadImages
。