2009-05-26 174 views
1

我写了一个Objective-C类,并在iPhone项目的几个视图中使用它的共享实例。它的成员变量包括bools,ints,NSStrings和一个NSNumber。共享实例似乎在我的应用程序范围内工作得很好,除非在第二次或以后访问共享实例时,调试器告诉我的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]; 

而在以同样的方式另一种观点。但第二次访问时,毛工会员超出了范围,但其他一切都很好 - 这就是为什么我难倒了。有任何想法吗?

回答

4

为什么你手动编写grossWage访问器(updateGrossWagegetGrossWage)?你确定你只是简单地分配给定的总工资,而不是保留或复制它?当呼叫者摆脱他的工资总额实例的这种方式,您将在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和他博客上的其他文章。

+0

我写了访问器,正如我在开始时所预期的那样,我可能想要对成员执行投射或其他操作......但现在看起来我为了简单起见就可以取消它们。我只是尝试绕过访问器方法,将grossWage定义为@property并直接设置它,它似乎已经完成了这个技巧......非常感谢!如果事实证明这不是问题,我会回来的。看起来我需要更多地阅读内存管理。 – moigno 2009-05-26 12:05:54

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 

看看是否没有清除它。

2

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

0

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