2010-08-04 3 views
2

Я работаю над проектом, где у меня есть класс, который имеет свойство 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». Предупреждение, очевидно, не останавливает создание приложения, но я просто пытаюсь выяснить, как с ним бороться. Это правильный способ сделать это? Есть ли способ остановить это предупреждение?

ответ

5

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

[myView performSelector:@selector(myMethod)]; 

(Так что компилятор не проверяет вызов метода на всех)

Или, лучше:

[(MyViewClass *)myView myMethod]; 

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

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

if ([myView isKindOfClass:[MyViewClass class]]) { ... 
+0

Проверка, отвечает ли объект сообщения, как правило, считается лучше. Просить класс - это круговой способ узнать, будет ли код отвечать на ваше сообщение. – Chuck

+0

Предположительно, идея здесь заключается в написании кода, который применяется только к пользовательскому подклассу. Ответит ли он на селектор, но если вы делаете несколько вызовов одновременно или просто убедитесь, что ваш код будет делать именно то, что вы ожидаете, проверка класса - это то, что я сделал бы. – jtbandes

+0

Проверка класса также недостаточна; Затем я должен проверить версию класса (если это возможно). Сравнивая его с тем, что было сделано в JavaScript-коде, он хотел бы проверить браузер, используемый для просмотра страницы, чтобы проверить, доступна ли функция JavaScript. – kiamlaluno

1

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

[myView performSelector:@selector(myMethod)]; 
1

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

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

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

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

    [myView performSelector:@selector(myMethod)]; 
    
Смежные вопросы