неперехваченное исключение ‘Исключение NSInvalidArgumentException’ -> Objective C

#objective-c

#objective-c

Вопрос:

Я пробовал пример программы thread от Google, и я получаю исключение во время выполнения.

Есть ли какой-нибудь веб-сайт, который дает пример того, как использовать циклы выполнения вместе с потоками. Мне нужно установить два события и запустить поток и параллельно выполнить другую функцию.

 // Runner.m

#import "Runner.h"

@implementation Runner

    - (void)rumMe:(id)ignored {

        NSLog(@"Running with threads!!");
    }

@end

// Runner.h

@interface Runner : NSObject

    -(void)rumMe:(id)ignored;

@end

// Thread1.m

#import <Foundation/Foundation.h>
#import "Runner.h"

int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    Runner* runner = [Runner new]; 
    [NSThread detachNewThreadSelector:@selector(runMe:) toTarget:runner withObject:nil];
    [pool drain];
    return 0;
}
  

Исключение во время выполнения:

 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** 
-[NSThread initWithTarget:selector:object:]: target does not implement selector (*** 
-[Runner runMe:])'
  

Комментарии:

1. Хорошо, немного почитав, вы, вероятно, сможете использовать new, так что проблема не в этом

2. Это опечатка. Посмотрите на объявление вашего метода: ru m Me: и ваш аргумент для detachNewThreadSelector: . ru n Me

3. @Josh: Аргумент, который я передаю в detachNewThreadSelector, является (runMe:), а не как (runMe)

4. Я не говорю о двоеточии; эта часть верна. У вас есть m в вашем объявлении и n в вашем вызове.

5. @Josh: правильно указано. Спасибо. Теперь оно выполняется без каких-либо исключений. Но он не выводит мне строки, «выполняемые с потоками», когда поток вызывает метод selector-runMe. почему это так.

Ответ №1:

Первая часть: у вас была опечатка

 // method declaration
rumMe:   with an _m_
// call
runMe:   with an _n_
  

Вторая часть: ваша основная функция возвращает и вызывает завершение программы до того, как вы дадите потоку шанс что-либо сделать. В этом простом примере вы могли бы просто

 sleep(2);
  

сразу после вызова detachNewThreadSelector:

В более сложных случаях может потребоваться выполнить вызов CFRunLoopRun(); в главном потоке или предпринять другие действия, чтобы сохранить второй поток в рабочем состоянии.

Комментарии:

1. Кейсвелл: Спасибо, что разъяснили мне суть потоковой обработки. будет выполняться некоторая сложная программа с потоковой обработкой.

Ответ №2:

Вы допустили опечатку. Метод в Runner определен как rumMe , но в основной программе, которую вы используете runMe .