NSInvalidArgumentException при вызове селектора с аргументами - PullRequest
0 голосов
/ 20 апреля 2011

Я пытаюсь выполнить метод, используя селектор с одним NSString в качестве параметра и не удается. Я видел много подобных вопросов (и ответов) и пробовал большинство решений, но безуспешно. Пожалуйста, смотрите код и ошибки ниже:

My MainView.m - это мой контроллер вида, и у него есть метод:

-(void)displayMessageOnTextView:(NSString *)message
{
    [tv1 setText:message];
}

А в MainView.h:

@interface MainView : UIViewController {
    UITextView *tv1;
}

-(void)displayMessageOnTextView:(NSString *)message;
....

У меня есть другой поток, который запускается MainView (это из MainView.m):

- (void) runTest
{
    MyThread *t = [[MyThread alloc] initWithInt:13253];
    [t setMainView:self];
    [t run];
    [t release];
}

и MyThread.m:

#import "MyThread.h"
#import "MainView.h"

@implementation MyThread

MainView *_view;
-(id)initWithInt:(int)someInt{
    _view = NULL;
    return self;
}

-(void)setMainView:(MainView*)view
{
    _view = view;
}

-(int)run{
    NSString *s = [NSString stringWithFormat:@"Display on Gui:%d", 1];
    [_view performSelectorOnMainThread:@selector(displayMessageOnTextView:message:) withObject:s waitUntilDone:YES];
}

@end

Ошибка:

2011-04-20 02:08:11.553 myApp[22627:207] -[MainView displayMessageOnTextView:message:]: unrecognized selector sent to instance 0x4e383a0
2011-04-20 02:08:11.555 myApp[22627:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MainView displayMessageOnTextView:message:]: unrecognized selector sent to instance 0x4e383a0'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00dc55a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x00f19313 objc_exception_throw + 44
    2   CoreFoundation                      0x00dc70bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00d36966 ___forwarding___ + 966
    4   CoreFoundation                      0x00d36522 _CF_forwarding_prep_0 + 50
    5   Foundation                          0x0079e94e __NSThreadPerformPerform + 251
    6   CoreFoundation                      0x00da68ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    7   CoreFoundation                      0x00d0488b __CFRunLoopDoSources0 + 571
    8   CoreFoundation                      0x00d03d86 __CFRunLoopRun + 470
    9   CoreFoundation                      0x00d03840 CFRunLoopRunSpecific + 208
    10  CoreFoundation                      0x00d03761 CFRunLoopRunInMode + 97
    11  GraphicsServices                    0x00ffd1c4 GSEventRunModal + 217
    12  GraphicsServices                    0x00ffd289 GSEventRun + 115
    13  UIKit                               0x00025c93 UIApplicationMain + 1160
    14  myApp                               0x000024c9 main + 121
    15  myApp                               0x00002445 start + 53
)
terminate called after throwing an instance of 'NSException'

Примечание:
Я новичок в программировании на Objective-C (и, как правило, на iOS), поэтому любые замечания, касающиеся правил кодирования и наилучшей практики, будут оценены (даже если они не связаны с моим вопросом, но связаны с моим кодом)

Ответы [ 2 ]

3 голосов
/ 20 апреля 2011

Ваш метод был объявлен как

-(void)displayMessageOnTextView:(NSString *)message;

Это означает, что имя метода - displayMessageOnTextView:, а соответствующий селектор - @selector(displayMessageOnTextView:). Обратите внимание, что имя метода не включает имена параметров (переменных).

В вашем -run методе измените

[_view performSelectorOnMainThread:@selector(displayMessageOnTextView:message:)
                        withObject:s
                     waitUntilDone:YES];

до

[_view performSelectorOnMainThread:@selector(displayMessageOnTextView:)
                        withObject:s
                     waitUntilDone:YES];

и эта ошибка во время выполнения не должна повторяться.

Для записи объявление метода, соответствующее displayMessageOnTextView:message:, будет иметь вид:

- (void)displayMessageOnTextView:(type1)parameter1 message:(type2)parameter2;
2 голосов
/ 20 апреля 2011

Этот метод:

-(void)displayMessageOnTextView:(NSString *)message

имеет селектор displayMessageOnTextView:. Название самого параметра (message в вашем случае) не отображается в селекторе. (Это должно быть интуитивно понятно: имя не обязательно появляется при вызове метода, поэтому оно не отображается в селекторе.) Поэтому вам нужно использовать @selector(displayMessageOnTextView:).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...