当我想要intValue时,如何防止自己意外使用NSNumber的指针?

时间:2009-12-13 22:52:10

标签: java objective-c cocoa nsnumber autoboxing

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

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

//img is a managed object that I have fetched

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

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

问题是这种情况完全无声地发生 - 没有编译器错误或警告。有时候,当这个愚蠢,愚蠢的问题出现时,我会花太长时间调试。

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

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

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

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

或者类似地,假设我想计算CS部门中所有课程的平均注册限制。

4 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:3)

这仅适用于处理Core Data,但如果您使用MOGenerator为Core Data对象生成类(我建议您仍然这样做),则可以使用-[propertyName]Value方法直接访问返回NSNumber s:

的属性的正确值
// These two methods are identical when called on a class 
// which was generated with MOGenerator
[[object imageID] intValue];
[object imageIDValue];

答案 2 :(得分:3)

  

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

使用NSArray's and NSSet's @avg operator很容易。当然,这会返回一个NSNumber,它会让你回到问题#2:

  

假设我想比较课程编号:

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

我认为你的意思是你冒的问题是省略intValue消息,从而将NSNumber对象的idint进行比较。

编译器会为此类比较提供警告。在Xcode中,将-Wextra添加到“其他C标志”构建设置中。有关更多警告选项,请参阅the full list of GCC warnings

答案 3 :(得分:0)

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