1

我有一个警告,我无法找到原因。

我正在遵循有关 Cocoa 编程的文本中的说明性代码,它实现了基于文档的图像幻灯片放映。此警告会导致 while 循环的执行次数超过正确的次数,从而导致程序崩溃。从作者网站下载的代码没有这个问题。

我认为这是我的版本中的一个简单错误,但仔细阅读两个版本的代码我无法发现任何差异。然后我系统地替换了我的版本中的每个 .h、.m、.xib 和其他资源文件,作者的版本清除了所有目标并在每次替换后重新构建。

但是,直到我最终将 .xcodeproj 文件替换为作者的版本,警告才会消失。此时警告清除并且代码运行而不会崩溃。然后我尝试了另一种方法,一次用我的 .h 和 .m 文件替换作者版本中的每个 .h 和 .m 文件,清理了所有目标,构建并再次没有警告或崩溃。我认为这可能是 .plist 文件中的一些设置,但交换该文件的两个版本似乎没有效果。我似乎能够将其缩小到 .xcodeproj 包中的 project.pbxproj 文件,但我看不出那里列出的任何构建设置如何导致问题。

如果有人可以对问题提供任何见解或可以推荐一种调试方法,我将不胜感激。带有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];
    }
}
4

1 回答 1

8

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) {

声明indexNSUInteger(由 byNSIndexSet用于索引的类型),并且该问题应该可移植地解决。

于 2011-09-03T16:39:11.590 回答