Предупреждение: сравнение всегда верно из-за ограниченного диапазона типов данных вызывает сбой
У меня есть предупреждение, что я не могу найти причину.
Я следую учебному коду в тексте по программированию Какао, который реализует слайд-шоу изображений на основе документа. Это предупреждение вызывает выполнение цикла while больше, чем правильное количество раз, что приводит к сбою программы. Код, загруженный с сайта автора, не имеет этой проблемы.
Я предположил, что это была простая опечатка в моей версии, но, внимательно читая обе версии кода, я не смог найти никаких отличий. Затем я систематически заменял каждый.h,.m,.xib и другие файлы ресурсов в моей версии авторской версией, очищая все цели и восстанавливая после каждой замены.
Однако предупреждение не исчезнет, пока я окончательно не заменю файл.xcodeproj на версию автора. В этот момент предупреждение сбрасывается, и код запускается без сбоев. Затем я поэкспериментировал с другим способом, заменив каждый из файлов.h и.m в авторской версии моими файлами.h и.m одновременно, очистил все цели, построил и снова никаких предупреждений или сбоев. Я подумал, что это может быть какой-то параметр в файле.plist, но замена двух версий этого файла, похоже, не имеет никакого эффекта. Кажется, я могу сузить его до файла project.pbxproj в пакете.xcodeproj, но я не вижу, как какой-либо из параметров сборки, перечисленных там, может вызвать проблему.
Я был бы признателен, если бы кто-нибудь мог предложить какое-либо понимание проблемы или порекомендовать метод для ее устранения. Предупреждение и связанный сегмент кода с циклом while следующие:
Построить предупреждение:
SlideShowDocument.m: In function '-[SlideShowDocument removeSlidesAtIndexes:]':
SlideShowDocument.m:191: warning: comparison is always true due to limited range of data type
Вывод консоли отладчика:
Slide Master[665:a0f] HIToolbox: ignoring exception '*** -[NSCFArray objectAtIndex:]: index (4294967295) beyond bounds (3)' that raised inside
Код:
- (void)removeSlidesAtIndexes:(NSIndexSet*)indexes;
{
NSMutableArray *slideList = [NSMutableArray array];
unsigned int index = [indexes firstIndex];
while (index != NSNotFound) {
Slide *slide = [mSlides objectAtIndex:index];
[slideList addObject:slide];
index = [indexes indexGreaterThanIndex:index];
}
if ([slideList count]) {
//remove the slides from the master list
[self recordSlideChange];
[mSlides removeObjectsInArray:slideList];
[self notifySlidesChanged];
}
}
1 ответ
NSUInteger
может быть больше, чем unsigned int
и это может зависеть от цели сборки (32 бита против 64 бита, LP64 против ILP64). От NSUInteger:
#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
Если это так для одной из ваших целей, NSNotFound
, который является значением перечисления, равным NSIntegerMax
( см. здесь) не вписывается в unsigned int
, Поэтому в игру вступит некоторое целочисленное продвижение, и вы никогда не достигнете равенства (о чем вам говорит компилятор) в этой строке:
while (index != NSNotFound) {
декларировать index
как NSUInteger
(тип, используемый NSIndexSet
для индексов) и эта проблема должна быть решена переносимо.