Цель-C: Зачем проверять ноль, прежде чем откликается на ToSelector? - PullRequest
27 голосов
/ 25 июня 2011

Я видел такой код:

if (delegate != nil && [delegate respondsToSelector:@selector(doSomething)]) ...

Но отправка сообщения на nil просто возвращает nil (что оценивается как NO), так почему бы просто не сделать:

if ([delegate respondsToSelector:@selector(doSomething)]) ...

Первый быстрее, если delegate == nil?В любом случае, я предпочитаю последнее, потому что это меньше кода.

И, less лучше, чем more.Это знает каждый профессионал Unix.

Ответы [ 3 ]

23 голосов
/ 25 июня 2011

objc_msgSend, функция, используемая для отправки динамических сообщений в Objective-C, немедленно проверяет первый аргумент (получатель сообщения) и возвращает, если он == ноль.Следовательно, единственными издержками при обмене сообщениями с нулевым значением является вызов динамически связанной библиотечной функции, который немного дороже, чем вызов «внутри двоичной» функции.В целом, является ли один подход более эффективным, чем другой?Составные условные операторы обычно требуют дополнительного ветвления, поэтому ответ не определим, не смотря на код, сгенерированный компилятором, но, что более важно, для профилирования работающей программы.Преждевременная оптимизация - это плохая вещь ™, но я поздравляю вас за то, что вы на самом деле учитываете эффективность и ставите под сомнение такие «идиомы», как этот.

5 голосов
/ 25 июня 2011

Вы правы. Это технически ненужная служебная нагрузка в Obj-C, поскольку любое сообщение, отправленное на nil, автоматически возвращает nil. Однако, если вы проигнорируете вызов respondsToSelector:, сначала проверив, является ли он nil, вы пропустите служебную информацию вызова respondsToSelector:. Так было бы быстрее, но насколько я не уверен.

0 голосов
/ 12 марта 2012

Здесь есть синтаксическая проблема - если вы отправляете -respondsToSelector объекту nil, он всегда будет возвращать nil. Вот почему ты так поступил.

...