2

我正在尝试创建 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:),但没有成功。

使用参数定义选择器和函数的正确方法是什么?

谢谢。

4

2 回答 2

5

定义带参数的 a 的正确方法SEL是为每个参数使用冒号 ( ":") 字符,因此在您的情况下,选择器将如下所示:

@selector(loadImagesWithOperation:)

所以,你的NSInvocationOperation对象应该像这样初始化:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
               selector:@selector(loadImagesWithOperation:)
                 object:params];

哦,顺便说一句,您的NSArrayin初始化时存在内存泄漏getImages:

NSArray * params = [NSArray arrayWithObjects:
      [[NSNumber alloc] initWithInt: bounds.location],
      [[NSNumber alloc] initWithInt: bounds.length]];

这会添加已经具有 aretainCount的对象,1因为您正在使用+alloc,因此当它们被添加到 时NSArray,它们会收到-retain消息,从而增加retainCountto 2

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

这个问题有三种解决方案:

  1. 在将autorelease这些对象添加到NSArray.
  2. 使用NSNumbernumberWithInt:类方法来获取一个自动释放的NSNumber对象。
  3. 创建对这些NSNumber对象的引用,将它们添加到 中NSArray,然后在添加时向它们发送-release消息。
于 2011-01-24T22:53:27.813 回答
3

一切都变好了。我尝试在@selector 的代码块中使用不同的语法,例如@selector(loadImagesWithOperation:) 和@selector(loadImagesWithOperation:bounds:),但没有成功。

initWithTarget:selector:object:接受一个可以完全接受 0 或 1 个参数的选择器,不多(不是两个)。那一个论点必须是一个对象。如果您需要更多参数,请使用块或重构您的代码(传递一个包含其余对象的数组是一个潜在的解决方案,是的 - 有点像您在该代码中所做的(尽管请注意内存泄漏)。

崩溃与您显示的代码无关。发布崩溃。

另请注意,get在 Cocoa/iOS 中,开头的方法具有非常特定的含义,并且不用于这种模式。我会建议loadImages

于 2011-01-26T15:55:39.227 回答