NSNumber 超出范围?

发布于 2024-07-22 13:14:15 字数 1415 浏览 10 评论 0原文

我编写了一个 Objective-C 类,并在 iPhone 项目中的多个视图中使用它的共享实例。 它的成员变量包括 bools、ints、NSStrings 和一个 NSNumber。 共享实例似乎在我的应用程序范围内工作得很好,除了 NSNumber 之外,一旦第二次或后续访问共享实例,调试器告诉我“超出范围”。

这是我正在做的事情的快速概述...

// UserData.h
@interface UserData : NSObject {
    TaxYears selectedTaxYear;
    NSNumber *grossWage; // <--- this is the troublesome member

// ...

    NSString *other;
    int age;

}
+ (UserData *)getSharedUserData;

@end

// UserData.m
#import "UserData.h"

@implementation UserData

static UserData *sharedUserData = nil;  // Points to the shared object

+ (UserData *)getSharedUserData {
    if(sharedUserData == nil) {
        sharedUserData = [[UserData alloc] initWithTaxYear:0];
        [[NSNotificationCenter defaultCenter]
         addObserver:sharedUserData
         selector:@selector(doTerminate:)
         name:UIApplicationWillTerminateNotification
         object:nil];
    }
    return sharedUserData;
}

- (id)initWithTaxYear:(TaxYears)theTaxYear {
    if ((self = [super init])) {

    }
    return self;
}
- (void)updateGrossWage:(NSNumber *)theGrossWage {
    grossWage = theGrossWage;
}
- (NSNumber *)getGrossWage {
    return grossWage;
}
// ...
@end

因此可以在一个视图中访问它,如下所示:

UserData *userData
userData = [[UserData getSharedUserData] retain];

并以相同的方式在另一个视图中访问。 但第二次访问时,grossWage 成员超出了范围,但其他一切都很好 - 这就是我感到困惑的原因。 有任何想法吗?

I've written an Objective-C class and I'm using a shared instance of it across several of the views in my iPhone project. Its member variables include bools, ints, NSStrings and one NSNumber. The shared instance seems to work just fine across the scope of my application, except for the NSNumber which the debugger tells me is "out of scope" once the shared instance has been accessed for the 2nd or subsequent times.

Here's a quick overview of what I'm doing...

// UserData.h
@interface UserData : NSObject {
    TaxYears selectedTaxYear;
    NSNumber *grossWage; // <--- this is the troublesome member

// ...

    NSString *other;
    int age;

}
+ (UserData *)getSharedUserData;

@end

// UserData.m
#import "UserData.h"

@implementation UserData

static UserData *sharedUserData = nil;  // Points to the shared object

+ (UserData *)getSharedUserData {
    if(sharedUserData == nil) {
        sharedUserData = [[UserData alloc] initWithTaxYear:0];
        [[NSNotificationCenter defaultCenter]
         addObserver:sharedUserData
         selector:@selector(doTerminate:)
         name:UIApplicationWillTerminateNotification
         object:nil];
    }
    return sharedUserData;
}

- (id)initWithTaxYear:(TaxYears)theTaxYear {
    if ((self = [super init])) {

    }
    return self;
}
- (void)updateGrossWage:(NSNumber *)theGrossWage {
    grossWage = theGrossWage;
}
- (NSNumber *)getGrossWage {
    return grossWage;
}
// ...
@end

So it is accessed in one view like this:

UserData *userData
userData = [[UserData getSharedUserData] retain];

And in another view in the same way. But the second time it is accessed, the grossWage member is out of scope, but everything else is fine - this is why I'm stumped. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

七度光 2024-07-29 13:14:15

为什么要手动编写 grossWage 访问器(updateGrossWagegetGrossWage)? 并且您确定您只是想简单地分配给定的总工资而不是保留或复制它吗? 这样,当调用者删除他的总工资实例时,您最终将在 userData 对象中获得已释放的总工资:

NSNumber grossWage = [[NSNumber numberWithInt:12] retain];
[userData updateGrossWage:grossWage];
[grossWage release];
// Now userData’s grossWage points to released object.

这可能是问题的原因。 如果没有,我建议发布一小段完整的示例代码 - 没有通知内容并带有调用上下文。


PS 像您的 UserData 这样的共享对象通常对您的设计不利(=&nbsp;导致代码痛苦),例如参见 Miško Hevery 的这篇文章 以及他博客上的其他文章。

Why do you write the grossWage accessors (updateGrossWage and getGrossWage) by hand? And are you sure you simply want to simply assign the given gross wage instead of retaining or copying it? This way when the caller gets rid of his gross wage instance you will end up with released gross wage in the userData object:

NSNumber grossWage = [[NSNumber numberWithInt:12] retain];
[userData updateGrossWage:grossWage];
[grossWage release];
// Now userData’s grossWage points to released object.

This could be the cause of the problem. If not, I’d suggest posting a smaller piece of complete example code – without the notification stuff and with the calling context.


P.S. Such shared objects as your UserData are usually bad for your design (= leading to pain in code), see for example this article by Miško Hevery and other articles on his blog.

酒废 2024-07-29 13:14:15

您遇到麻烦的原因不是因为您应该或不应该使用属性,而是因为您没有遵循内存管理规则。 NSNumber 是一个对象,应该保留在您的 setter 中。 将其更改为属性将解决眼前的问题,因为 Objective-C 正在为您处理工作,但您仍然应该检查内存管理,因为 100% 确定您将继续遇到问题,直到您适应为止。

The reason you're having trouble is not because you should or shouldn't be using a property, but because you're not following memory management rules. NSNumber is an object, and should be retained in your setter. Changing it to a property will fix the immediate problem because Objective-C is handling the work for you, but you should still review memory management because it's 100% certain you're going to continue to have problems until you're comfortable with it.

作妖 2024-07-29 13:14:15

跟进@zoul的观点...

我会声明grossWage是一个属性,并综合getter和setter。 我认为二传手是你问题的根源。

// in UserData.h
@interface UserData : NSObject {
    NSNumber *grossWage; 
}

@property (nonatomic, retain) NSNumber *grossWage; 



// in UserData.m
#import "UserData.h"

@implementation UserData
@synthesize grossWage;

// then do NOT create getters and setters for grossWage

看看这是否还不能清除。

Following up on @zoul's point...

I would declare that grossWage is a property, and synthesize the getters and setters. I think that setter is the source of your problem.

// in UserData.h
@interface UserData : NSObject {
    NSNumber *grossWage; 
}

@property (nonatomic, retain) NSNumber *grossWage; 



// in UserData.m
#import "UserData.h"

@implementation UserData
@synthesize grossWage;

// then do NOT create getters and setters for grossWage

See if that does not clear it up.

陈年往事 2024-07-29 13:14:15

这听起来很愚蠢,但是检查是否被零除。 我有同样的错误,原因是除以零。

It sounds stupid but check for division by zero. I had the same error and the reason was a division by zero.

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