2

我真正喜欢的 Java 功能之一是自动装箱,其中编译器自动在原语及其包装类之间进行转换。

我正在用 Objective-C/Cocoa 编写一个核心数据应用程序,我发现以编程方式处理我的整数属性令人沮丧。原因如下:

//img is a managed object that I have fetched

NSString* filename = [NSString stringWithFormat:@"image%d.png", [[img valueForKey:@"imageID"] intValue]];  

如果我碰巧忘记了intValue我有时会忘记的消息,那么传递给的 intstringWithFormat:实际上就是指针值。

问题是这完全无声地发生——没有编译器错误或警告。有时,当这个愚蠢、愚蠢的事情成为问题时,我会花太多时间进行调试。

有没有办法改变我的编程风格或编译器设置以防止我陷入那个陷阱?

编辑:我不清楚上面的例子只是我遇到麻烦的许多地方之一。这是另一个与字符串无关的假设示例:

实体CollegeClass有两个整数属性:courseNumberenrollmentLimit。假设我想比较课程编号:

//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
    NSLog(@"undergraduate class");
}

或者类似地,假设我想计算 CS 部门所有课程的平均入学人数限制。

4

4 回答 4

7

您可以使用 %@ 将 NSNumber 直接转换为字符串而不是 %d。

它实际上会采用任何基于 NSObject 的类并将其转换为我相信的字符串。

于 2009-12-13T22:58:22.820 回答
3

这仅在处理 Core Data 时适用,但如果您使用MOGenerator为您的 Core Data 对象生成类(我还是建议这样做),那么您可以使用-[propertyName]Value方法直接访问返回NSNumbers 的属性的正确值:

// These two methods are identical when called on a class 
// which was generated with MOGenerator
[[object imageID] intValue];
[object imageIDValue];
于 2009-12-13T23:04:45.617 回答
3

…假设我想计算 CS 部门所有课程的平均入学人数限制。

使用NSArray 和 NSSet 的@avgoperator很容易做到这一点。当然,这会返回一个 NSNumber,这会让你回到问题 #2:

假设我想比较课程编号:

//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
    NSLog(@"undergraduate class");
}

我假设您的意思是您面临的问题是省略intValue消息,从而将 NSNumber 对象idint.

编译器会为此类比较提供警告。在 Xcode 中,添加-Wextra到“Other C Flags”构建设置。有关更多警告选项,请参阅GCC 警告的完整列表

于 2009-12-14T07:32:32.190 回答
0

如果尚未打开“Typecheck calls to printf/ scanf”警告,请打开它。这目前对 NS/CFString 格式没有帮助,但我已经为此提交了雷达增强请求 (x-radar://problem/7375186)。当然,欢迎您提交自己的文件。

于 2009-12-13T23:53:40.993 回答