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

发布于 2024-08-15 03:20:26 字数 910 浏览 3 评论 0原文

我真正喜欢的 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 有两个整数属性:courseNumberenrollmentLimit。假设我想比较课程编号:

//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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼藏柔 2024-08-22 03:20:26

您可以使用 %@ 将 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.

李不 2024-08-22 03:20:26

…假设我想计算计算机科学系所有课程的平均入学限制。

使用 NSArray 和 NSSet 的 <代码>@avg运算符。当然,这会返回一个 NSNumber,这会让你回到问题#2:

假设我想比较课程编号:

//classFoo 是我获取的 NSManagedObjects
if ([[classFoo valueForKey@"courseNumber"] intValue] < 400) {
    NSLog(@"本科班");
}

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

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

… suppose I want to compute the average enrollment limit for all the classes in the CS department.

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:

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");
}

I assume you mean that the problem you risk is omitting the intValue message, thereby comparing the NSNumber object's id to the int.

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.

黑凤梨 2024-08-22 03:20:26

这仅适用于处理核心数据时,但如果您使用 MOGenerator 为核心数据生成类对象(无论如何我都建议这样做),然后您可以使用 -[propertyName]Value 方法直接访问返回 NSNumber 的属性的正确值:

// These two methods are identical when called on a class 
// which was generated with MOGenerator
[[object imageID] intValue];
[object imageIDValue];

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 return NSNumbers:

// These two methods are identical when called on a class 
// which was generated with MOGenerator
[[object imageID] intValue];
[object imageIDValue];
玩套路吗 2024-08-22 03:20:26

打开“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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文