2009-05-26 173 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

這聽起來很愚蠢,但檢查零除。我有同樣的錯誤,原因是一個除零。