2012-01-07 1 views
10

Я получаю предупреждениеPerformSelector предупреждение

PerformSelector может привести к утечке, потому что его селектор неизвестно

В коде:

- (void) callDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err 
{ 
    assert([NSThread isMainThread]); 
    if([delegate respondsToSelector: selector]) 
    { 
     if(arg != NULL) 
     { 
      //this line the warning 
      [delegate performSelector: selector 
          withObject: arg 
          withObject: err]; 
     } 
     else 
     { 
      //this line the warning 
      [delegate performSelector: selector 
          withObject: err]; 
     } 
    } 
    else 
    { 
     NSLog(@"Missed Method"); 
    } 
} 

Заголовок:

@interface Topscore : UIViewController <NSObject> { 

// 
} 
+0

возможно дубликат [performSelector может привести к утечке, потому что его селектор неизвестно] (http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak- потому что-его-selector-is-unknown) –

+0

Я думаю, что это [хороший пост] (http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown) Объясните проблему очень хорошо! Может быть, это будет полезно! – monjer

ответ

4

Это предупреждение, сгенерированное компилятором, потому что во время компиляции использовался -Wundeclared-selector, а автоматический подсчет ссылок (ARC) включен. Это может быть, в общем, безопасно проигнорировано, так как очевидно, что селектор в переменной с именем «селектор» неизвестен во время компиляции, так как он будет иметь свое значение, назначенное во время выполнения.

+0

Спасибо, но в моем приложении он возвращает NSLOG; Пропущенный метод. Это неверно – Blazer

+0

Это означает, что объект не реализует этот метод (таким образом, он не отвечает указанному селектору). Это не вызывает утечку памяти, потому что, если достигнута ветка «else» структуры if, метод - [delegeta performSelector] не был вызван, поэтому он не смог сохранить объект, поэтому утечка памяти не происходит. –

+0

Вы помните, что для каждого аргумента помещали двоеточие за селектором? Селектор для метода '- (void)WithObject: (id) arg1;' на самом деле '@selector (methodWithObject:)'. Двоеточие является частью этого. – weezor

42

Ваш if ... respondsToSelector: selector не будет работать, потому что ваш selector - это просто имя метода. В вашем случае вам нужно проверить

if ([delegate respondsToSelector: @selector(method::)] 

и для другого случая только для method:.

Во всяком случае, вы можете подавить предупреждение вроде этого:

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
    [self performSelector:nextView]; 
#pragma clang diagnostic pop 
+1

Выборочное игнорирование предупреждения является супер удобным , Благодарю. – Megasaur

+5

Я понял, что достаточно использовать '#pragma clang diagnostic ignored '-Warc-performSelector-leaks' 'в начале реализации класса. –

+2

@Julian, но тогда вы не знаете, есть ли реальная проблема где-то еще в вашей реализации класса.С другой стороны, вы можете отключить предупреждение в глобальном масштабе в своих настройках сборки, если не возражаете ... – Klaas

3

Вы также можете использовать objc_msgSend вместо performSelector, как описано here.

+2

Но это кажется излишним ... – ZhangChn

+0

Почему перебор? Это просто другой способ сделать то же самое, не так ли? –

0

Самый простой способ добавляет этот макрос к вашему PCH файл. Или .m файл ..

#pragma GCC diagnostic ignored "-Wundeclared-selector"