1

我已经编写了一个 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 成员超出了范围,但其他一切都很好——这就是我难过的原因。有任何想法吗?

4

4 回答 4

4

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

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

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


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

于 2009-05-26T11:48:30.370 回答
2

您遇到问题的原因不是因为您应该或不应该使用属性,而是因为您没有遵循内存管理规则。NSNumber 是一个对象,应该保留在您的设置器中。将其更改为属性将解决直接问题,因为 Objective-C 正在为您处理工作,但您仍应查看内存管理,因为它 100% 确定您将继续遇到问题,直到您对它感到满意为止。

于 2009-05-26T12:58:29.417 回答
0

跟进@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

看看这是否清除它。

于 2009-05-26T12:08:34.090 回答
0

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

于 2009-05-26T13:49:35.977 回答