Intereting Posts
Загрузка обновления приложения с помощью другого идентификатора найти широту и долготу в строке Не удалось обновить статус автоматического макета: агент разбился Как выделить пользовательское время в UILocalnotification? iOS UILabel не перерисовывается до нового размера IOS. Анализ и оценка логических и математических выражений Стандартный дескриптор сортировки данных с компаратором Как мы сортируем результаты выборки данных ядра на основе BOOL Zbar lib на iOS на TabItem в XE6 Почему функция nextDateAfterDate не работает должным образом? Как интегрировать радарную накладку для отображения погоды? OpenGL ES Performance Detective не может собирать доказательства (ошибки: «контексты с различными уровнями API OpenGL ES») IOS, как получить диалог расширенного разрешения Facebook UICollectionView hitTest -> нормальное поведение MKPointAnnotation была освобождена, а наблюдатели ключевых значений

Оценка (NSIntegers) внутри if-statement Objective-C

Я сомневаюсь, почему эта работа правильна:

NSInteger row = indexPath.row; NSInteger preloadTrigger = self.nodes.count - 20; if (row >= preloadTrigger) { [self.loader loadNextposts]; } 

И это не так (просто пропускает if-statement):

 if (indexPath.row >= self.nodes.count - 20) { [self.loader loadNextposts]; } 

когда значение self.nodes.count - 20 отрицательно.

Однако, когда значение выражения положительное, оно отлично работает.

Очень странное поведение, поскольку я не вижу семантической разницы в двух выражениях.

Обновление: Итак, я решил проверить его:

 (lldb) po self.nodes.count - 20 18446744073709551601 (lldb) po preloadTrigger -15 

Согласно Apple Docs , свойство count является NSUInteger в NSUInteger -C.

Когда вы пишете:

  NSInteger preloadTrigger = self.nodes.count - 20; 

Фактически вы выполняете count до объекта NSInteger и можете иметь отрицательное значение, если count не превышает 20.

Но когда вы пишете:

 (indexPath.row >= self.nodes.count - 20) 

count – объект NSUInteger , и вычесть 20 из него всегда приведет к положительному числу (кстати, огромному).

Поскольку node.count – NSUInteger, а row – NSInteger. Unsigned integer – 20 никогда не является отрицательным значением, но дает огромное положительное значение, когда вы ожидаете, что оно будет отрицательным.

Я добавлю некоторые объяснения к другому, правильные ответы.

Итак, вот как это получается:

self.nodes.count имеет тип NSUInteger, который совпадает с unsigned long int в 64-битных системах или, альтернативно, unsigned int в 32-битных системах.

Литерал 20 имеет тип int .

Когда вы формируете выражение self.nodes.count - 20 , 20 «продвигается» к неподписанному целочисленному типу другого операнда ( self.nodes.count ), потому что он имеет более широкий диапазон этих двух.

Это связано с тем, что, когда оба операнда имеют типы разного размера, меньший получает повышение до большего, чтобы сделать их равными и вычислять результат в этих терминах (в аппаратном обеспечении арифметические операции между значениями разных типов на самом деле не определены – представления бит различаются).

Проблема в том, что в обмен на возможность представления более широкого диапазона положительных значений с одинаковой длиной бита беззнаковые целые числа не могут представлять отрицательные значения. Итак, когда 20 больше, чем self.nodes.count , результат «обертывается» к большому целому числу без знака.

С другой стороны, indexPath.row тоже представляет собой целое число без знака ( NSUInteger ), поэтому вы сравниваете относительно небольшое значение строки с огромным результатом операции вычитания; тест:

 if (indexPath.row >= self.nodes.count - 20) 

… всегда терпит неудачу (левая сторона меньше).

Если вы сначала передали оба результата в целое число со знаком, а затем сравнили эти целые числа:

 NSInteger row = indexPath.row; NSInteger preloadTrigger = self.nodes.count - 20; if (row >= preloadTrigger) { 

… тогда нет обертывания / недочета, и вы получите ожидаемый результат.