Это правильно?Использование executeSelector вместо простого вызова метода - PullRequest
0 голосов
/ 15 октября 2011

Я пытаюсь закрыть суперпредставление с помощью этого метода [self.superview buttonPressedClose];

Я уже внедрил этот метод в своем суперпредставлении, и все работает.

Но это дает мне предупреждение" UIView может не отвечать на 'buttonPressedClose' " во время компиляции.

Если я изменю его на следующую строку, это не выдаст мне предупреждение, но это правильный способсделать это?

if ([self.superview respondsToSelector:@selector(buttonPressedClose)]) {
    [self.superview performSelector:@selector(buttonPressedClose) withObject:nil afterDelay:0.0];
}

Спасибо.

** Отредактированная опечатка ..

Ответы [ 2 ]

4 голосов
/ 15 октября 2011

Это опечатка или ваш код?

if ([self.superview respondsToSelector:@selector(buttonPressedClose)]) {
                                                   //  vv here
[self.superview performSelector:@selector(buttonPressedCLose) withObject:nil afterDelay:0.0];
}

Как правило, self.superview возвращает объект типа UIView, а ваш buttonPressedClose является пользовательским селектором, который не реализован в UIView. Вот почему вы получаете предупреждение.

Возможно, вы захотите привести self.superview к нужному вам типу, например ::

.
[(MyView *)self.superview buttonPressedClose];

или сделайте его еще более загадочным и приведите к id - компилятор не проверяет наличие селекторов:

[(id)self.superview buttonPressedClose];

Тем не менее, все вышеперечисленные решения немного вонючие.

Одна очень важная вещь, связанная с performSelector: с нулевой задержкой - она ​​не выполняет селектор на месте, а скорее отправляет выполнение селектора в цикл выполнения потока и выполняет его, когда управление возвращается к выполнению цикл (т. е. когда стек вызовов пуст). Так что в нормальных ситуациях вы бы не хотели его использовать.

0 голосов
/ 25 января 2012

"это правильный способ сделать это?"

Нет, нет причин делать это таким образом.afterDelay:0 используется только если вы не хотите выполнять его немедленно.Если вы хотите выполнить его немедленно, тогда вы должны использовать performSelector: без afterDelay:.

Но использование performSelector: напрямую, как это, не имеет смысла.Это эквивалентно и является более сложным способом непосредственного вызова метода.Предупреждение, которое вы получаете, является чисто статической проблемой проверки типов.Тип (UIView *) не обязательно должен иметь этот метод.Вам нужно привести его к ожидаемому типу представления, которое поддерживает метод, или привести к id, чтобы отключить проверку методов.Когда вы используете performSelector:, это также обходит статическую проверку типов методов, так что это не лучше, чем приведение к id и последующий вызов.

...