Цель-C: Зачем проверять ноль, прежде чем откликнется ToSelector:?
Я видел такой код:
if (delegate != nil && [delegate respondsToSelector:@selector(doSomething)]) ...
Но, отправив сообщение nil
просто возвращается nil
(который оценивает NO
) так почему бы просто не сделать
if ([delegate respondsToSelector:@selector(doSomething)]) ...
Первый быстрее, если delegate == nil
? В любом случае, я предпочитаю последнее, потому что это меньше кода.
А также, less
лучше, чем more
, Каждый профессионал Unix знает это.
3 ответа
objc_msgSend, функция, используемая для отправки динамических сообщений в Objective-C, немедленно проверяет первый аргумент (получатель сообщения) и возвращает, если он == ноль. Следовательно, единственными издержками при обмене сообщениями с нулевым значением является вызов динамически связанной библиотечной функции, который немного дороже, чем вызов "внутри двоичной" функции. В целом, является ли один подход более эффективным, чем другой? Сложные условные операторы обычно требуют дополнительного ветвления, поэтому ответ не определен, не смотря на код, сгенерированный компилятором, но, что более важно, для профилирования работающей программы. Преждевременная оптимизация - это плохая вещь, но я поздравляю вас с тем, что вы на самом деле учитываете эффективность и ставите под сомнение такие идиомы.
Ты прав. Это технически ненужные издержки в Obj-C, так как любое сообщение отправляется nil
вернусь nil
автоматически. Тем не менее, если вы игнорируете вызов respondsToSelector:
сначала проверив, если это nil
, тогда вы пропустите накладные расходы respondsToSelector:
вызов. Так было бы быстрее, но насколько я не уверен.
Здесь есть синтаксическая проблема - если вы отправляете -respondsToSelector объекту nil, он всегда будет возвращать nil. Вот почему вы бы так поступили.