我编写了一个Objective-C类,我在我的iPhone项目中的几个视图中使用了它的共享实例。其成员变量包括bools,int,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成员超出范围,但其他一切都很好 - 这就是为什么我很难过。有什么想法吗?
答案 0 :(得分:4)
为什么要手写grossWage
访问者(updateGrossWage
和getGrossWage
)?你确定你只想简单地分配给定的工资而不是保留或复制它吗?这样当调用者摆脱他的总工资实例时,你最终会在userData
对象中释放总工资:
NSNumber grossWage = [[NSNumber numberWithInt:12] retain];
[userData updateGrossWage:grossWage];
[grossWage release];
// Now userData’s grossWage points to released object.
这可能是问题的原因。如果没有,我建议发布一小段完整的示例代码 - 没有通知内容和调用上下文。
P.S。像UserData
这样的共享对象通常会对您的设计造成不利影响(导致代码痛苦),例如MiškoHevery的this article和他博客上的其他文章。
答案 1 :(得分:2)
您遇到问题的原因不是因为您应该或不应该使用属性,而是因为您没有遵循内存管理规则。 NSNumber是一个对象,应保留在您的setter中。将其更改为属性将解决当前问题,因为Objective-C正在为您处理工作,但您仍应该检查内存管理,因为100%确定您将继续遇到问题,直到您对此感到满意为止。
答案 2 :(得分:0)
跟进@ zoul的观点...
我会声明grossWage是一个属性,并合成getter和setter。我认为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
看看是否不清楚它。
答案 3 :(得分:0)
这听起来很愚蠢,但检查除零。我有同样的错误,原因是除零。