NSInvocationOperation определяет селектор с параметрами - PullRequest
2 голосов
/ 25 января 2011

Я пытаюсь создать 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:) , но не удалось.

Как правильно определить селектор и функцию с помощью параметров?

Спасибо.

Ответы [ 2 ]

5 голосов
/ 25 января 2011

Правильный способ определения 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, увеличивая таким образом retainCount до 2.

Когда этот NSArray освобожден, эти объекты не будут освобождены, потому что их retainCount будет 1, а не 0.

Существует три решения этой проблемы:

  1. Отправьте сообщение autorelease каждому из этих объектов, прежде чем они будут добавлены в NSArray.
  2. Использование *Метод класса 1037 * numberWithInt: для получения автоматически освобожденного объекта NSNumber.
  3. Создание ссылок на эти NSNumber объектов, добавьте их в NSArray, затем при добавлении отправьте им сообщение -release.
3 голосов
/ 26 января 2011

все становится хорошо. я пытался использовать другой синтаксис в @ селектора кодовый блок как @selector (loadImagesWithOperation :) а также @selector (loadImagesWithOperation: границы :), но не удалось.

initWithTarget:selector:object: принимает селектор, который может принимать ровно 0 или 1 аргумент, не более (не два). Этот один аргумент должен быть объектом. Если вам нужно больше аргументов, либо используйте блоки, либо реорганизуйте свой код (передача массива с остальными объектами внутри - это потенциальное решение, да - вроде как то, что вы делаете в этом коде (хотя обратите внимание на утечки памяти).

Сбой не связан с кодом, который вы показали. Опубликуйте сообщение об аварии.

Обратите внимание, что методы с get в заголовке имеют очень специфическое значение в Какао / iOS и не используются для этого типа паттернов. Я бы предложил loadImages.

...