2011-01-24 78 views
2

我想创建NSInvocationOperation选择这样,它应该调用对象的方法使用参数NSInvocationOperation定义使用参数

- (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

发布崩溃的回溯 – bbum 2011-01-25 17:41:30

回答

4

正确的方法来定义一个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]]; 

此补充说,已经有1一个retainCount因为你使用+alloc对象,所以当他们被添加到NSArray,它们会发出-retain消息,从而递增retainCount2

当这个NSArray被释放时,这些对象将不会被释放,因为它们的retainCount将是1而不是0

有三种解决这个问题:

  1. 发送autorelease消息给这些对象,他们被添加到NSArray之前。
  2. 使用NSNumbernumberWithInt:类方法获取自动发布的NSNumber对象。
  3. 创建对这些NSNumber对象的引用,将它们添加到NSArray,然后在添加后向它们发送-release消息。
+0

感谢您的快速回答,雅各布,但在某些情况下,此代码不起作用。选择器中的ame仍然会导致EXC_BAD_ACCESS。我被困。 – duganets 2011-01-24 23:03:29

3

一切都很好。我曾尝试 以使用@选择的 代码块不同的语法像 @selector(loadImagesWithOperation :) 和 @selector(loadImagesWithOperation:边界:), 但没有成功。

initWithTarget:selector:object:需要一个选择器,只能接受0或1个参数,不能多于(不是两个)。这一个论点必须是一个对象。如果您需要更多参数,请使用块或重构您的代码(将数组与其他对象一起传递是一个潜在的解决方案,是的 - 有点像您在代码中所做的事情(尽管注意内存泄漏)

崩溃是无关的,你已经显示的代码。发布崩溃。

还要注意的是在头部与get方法在可可/ iOS的一个非常特殊的意义,而不是用于这种模式。我建议loadImages