当我想要它的 intValue 时,如何防止自己意外使用 NSNumber 的指针?
我真正喜欢的 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
消息(我有时会这样做),那么传递给 stringWithFormat:
的 int 实际上是指针值。
问题是这完全是悄无声息地发生的——没有编译器错误或警告。有时,当这个愚蠢的问题出现时,我会花费太长时间进行调试。
有没有办法改变我的编程风格或编译器设置,以防止我陷入这个陷阱?
编辑:我不清楚上面的例子只是我遇到麻烦的许多地方之一。这是另一个与字符串无关的假设示例:
实体 CollegeClass
有两个整数属性:courseNumber
和 enrollmentLimit
。假设我想比较课程编号:
//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
NSLog(@"undergraduate class");
}
或者类似地,假设我想计算计算机科学系所有课程的平均入学限制。
One feature of Java that I really like is autoboxing, in which the compiler automatically converts between primitives and their wrapper classes.
I'm writing a Core Data application in Objective-C/Cocoa, and I'm finding it frustrating to deal with my integer attributes programmatically. Here's why:
//img is a managed object that I have fetched
NSString* filename = [NSString stringWithFormat:@"image%d.png", [[img valueForKey:@"imageID"] intValue]];
If I happen to forget the intValue
message, which I sometimes do, then the int that gets passed to stringWithFormat:
is actually the pointer value.
The problem is that this happens totally silently--no compiler error or warning. Sometimes I'll spend way too long debugging when this silly, stupid thing is the problem.
Is there a way to change my programming style or my compiler settings to prevent me from getting caught in that trap?
Edit: I wasn't clear about the fact that the above example is just one of many places where I run into trouble. Here's another hypothetical example that doesn't have to do with strings:
Entity CollegeClass
has two integer attributes: courseNumber
and enrollmentLimit
. Let's say I want to compare course numbers:
//classFoo is a NSManagedObjects I've fetched
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
NSLog(@"undergraduate class");
}
Or similarly, suppose I want to compute the average enrollment limit for all the classes in the CS department.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以使用 %@ 将 NSNumber 直接转换为字符串而不是 %d。
它实际上会接受任何基于 NSObject 的类并将其转换为我相信的字符串。
You can use %@ to convert a NSNumber directly to a string instead of the %d.
It will actually take any NSObject based class and convert it to a string I believe.
使用 NSArray 和 NSSet 的 <代码>@avg运算符。当然,这会返回一个 NSNumber,这会让你回到问题#2:
我假设您的意思是您面临的问题是省略
intValue
消息,从而将 NSNumber 对象的id
与int 进行比较
。编译器会针对此类比较发出警告。在 Xcode 中,将
-Wextra
添加到“Other C Flags”构建设置中。有关更多警告选项,请参阅GCC 警告的完整列表。This is easy to do with NSArray's and NSSet's
@avg
operator. Of course, that will return an NSNumber, which puts you back in problem #2:I assume you mean that the problem you risk is omitting the
intValue
message, thereby comparing the NSNumber object'sid
to theint
.The compiler offers a warning for such comparisons. In Xcode, add
-Wextra
to your “Other C Flags” build setting. For more warning options, see the full list of GCC warnings.这仅适用于处理核心数据时,但如果您使用 MOGenerator 为核心数据生成类对象(无论如何我都建议这样做),然后您可以使用
-[propertyName]Value
方法直接访问返回NSNumber
的属性的正确值:This is only applicable when dealing with Core Data, but if you use MOGenerator to generate classes for your Core Data objects (which I'd recommend doing anyway), you can then use
-[propertyName]Value
methods to directly access the correct value for properties which returnNSNumber
s:打开“Typecheck requests to
printf
/scanf
”警告(如果尚未打开)。目前,这对 NS/CFString 格式化没有帮助,但我已为此提交了雷达增强请求 (x-radar://problem/7375186)。当然,欢迎您提交自己的文件。Turn on the “Typecheck calls to
printf
/scanf
” warning, if it isn't on already. This doesn't currently help with NS/CFString formatting, but I've filed a Radar enhancement request (x-radar://problem/7375186) for that. You're welcome to file your own, of course.