Если объект откликается, все равно выдает предупреждение - PullRequest
2 голосов
/ 04 августа 2010

Я работаю над проектом, в котором у меня есть класс, который имеет свойство UIView.Я также определяю класс, который является подклассом UIView, который определяет определенный метод.Если у меня есть следующий код, я получаю предупреждение при сборке:

// In this example, myView is UIView property which *may* contain a UIView or 
// my subclassed-UIView which has the myMethod method
if([myView respondsToSelector:@selector(myMethod)]){
   [myView myMethod]
}

Предупреждение «UIView может не отвечать на« -myMethod ».Очевидно, что предупреждение не мешает созданию приложения, но я просто пытаюсь понять, как с ним бороться.Это правильный способ сделать это?Есть ли способ остановить это предупреждение?

Ответы [ 3 ]

5 голосов
/ 04 августа 2010

Предупреждение только потому, что компилятор не знает, является ли это представление вашим пользовательским подклассом. Конечно, во время выполнения это будет работать нормально, так как это будет подкласс. У вас есть два варианта исправить это:

[myView performSelector:@selector(myMethod)];

(поэтому компилятор вообще не проверяет вызов метода)

Или лучше:

[(MyViewClass *)myView  myMethod];

Таким образом, компилятор действует так, как будто объект действительно является вашим подклассом представления (после того, как вы выполните проверку, конечно).

В этом отношении, возможно, имеет смысл проверить ваш класс, а не метод:

if ([myView isKindOfClass:[MyViewClass class]]) { ...
1 голос
/ 04 августа 2010

Это статическое предупреждение о типизации, сообщающее, что тип переменной, объявленной как, не отвечает этому селектору.Поскольку вы фактически используете подкласс, который, как вы подтвердили, отвечает на селектор, вы знаете, что это не проблема, но компилятор не достаточно умен, чтобы понять это.Есть несколько способов это исправить.В порядке убывания безопасности:

  1. Приведите переменную к тому, что на самом деле означает, что отвечает на селектор, либо на определенный класс, либо на протокол.Вам все равно придется импортировать соответствующий заголовок, иначе компилятор будет подозревать, что вы что-то опечатали.Какой вариант лучше всего зависит от вашей ситуации (например, есть ли один «правильный» класс для приведения).

    [(id<SomeProtocolWiththatSelector>)myView myMethod];
    [(SomeUIViewSubclass *)myView myMethod];
    
  2. Приведите переменную к id, чтобы отключить статическую проверку типов.Вам все еще нужно импортировать заголовок с объявлением, чтобы компилятор знал, что какой-то метод существует, или он все равно выдаст предупреждение «Я не уверен, что это реальный метод».

    [(id)myView myMethod];
    
  3. Использование performSelector:.Это не будет делать никаких проверок во время компиляции, так что вам не нужно импортировать какие-либо заголовки, кроме Foundation, но компилятор также не будет перехватывать опечатки, поэтому любые ошибки, которые вы делаете, означают, что программа запускается во время выполнения.

    [myView performSelector:@selector(myMethod)];
    
1 голос
/ 04 августа 2010

Вы можете использовать:

[myView performSelector:@selector(myMethod)];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...