2009-05-26 9 views
1

Ich habe eine Objective-C-Klasse geschrieben und verwende eine gemeinsame Instanz für mehrere Ansichten in meinem iPhone-Projekt. Seine Mitgliedsvariablen umfassen bools, ints, NSStrings und eine NSNumber. Die gemeinsam genutzte Instanz scheint über den gesamten Umfang meiner Anwendung hinweg gut zu funktionieren, mit Ausnahme der NSNummer, von der der Debugger sagt, dass sie "außerhalb des Gültigkeitsbereichs" ist, sobald auf die gemeinsam genutzte Instanz zum zweiten oder nachfolgenden Mal zugegriffen wurde.NSNumber nicht verfügbar?

Hier ist ein kurzer Überblick über, was ich tue ...

// 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 ist es in einer Ansicht wie folgt zugegriffen:

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

Und in einer anderen Ansicht auf die gleiche Weise. Aber beim zweiten Zugriff ist das Mitglied von growWage nicht mehr im Einsatz, aber alles andere ist in Ordnung - deshalb bin ich ratlos. Irgendwelche Ideen?

Antwort

4

Warum schreiben Sie die grossWage Accessoren (updateGrossWage und getGrossWage) von Hand? Und sind Sie sicher, dass Sie einfach den gegebenen Bruttolohn zuweisen wollen, anstatt ihn zu behalten oder zu kopieren? Auf diese Weise, wenn der Anrufer seine Bruttolohn Instanz entledigt Sie mit freiBruttoLohn im userData Objekt wird am Ende:

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

Dies könnte die Ursache des Problems sein. Wenn nicht, würde ich vorschlagen, einen kleineren Teil des vollständigen Beispielcodes zu posten - ohne den Hinweis und den aufrufenden Kontext.


P.S. Solche gemeinsamen Objekte wie Ihre UserData sind normalerweise schlecht für Ihr Design (= führt zu Schmerzen im Code), siehe zum Beispiel this article von Miško Hevery und andere Artikel auf seinem Blog.

+0

Ich habe die Accessoren geschrieben, wie ich es am Anfang erwartet habe, dass ich Casting oder andere Manipulationen an den Mitgliedern durchführen möchte ... aber jetzt sieht es so aus, als könnte ich sie der Einfachheit halber beseitigen. Ich habe gerade versucht, die Accessor-Methode zu umgehen, die growWage als @property zu definieren und sie direkt zu setzen und es scheint den Trick geschafft zu haben ... vielen Dank! Wenn sich herausstellt, dass dies nicht das Problem war, komme ich zurück. Sieht so aus, als müsste ich etwas mehr über die Speicherverwaltung lesen. – moigno

0

Im Anschluss an Punkt des @ Zoul ...

Ich würde erklären, dass grossWage eine Eigenschaft ist, und die Getter und Setter synthetisieren. Ich denke, dass Setter die Quelle deines Problems ist.

// 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 

Schauen Sie, ob das nicht klärt.

2

Der Grund, warum Sie Probleme haben, liegt nicht daran, dass Sie eine Eigenschaft verwenden sollten oder sollten, sondern weil Sie die Speicherverwaltungsregeln nicht befolgen. NSNumber ist ein Objekt und sollte in Ihrem Setter beibehalten werden. Wenn Sie es in eine Eigenschaft ändern, wird das unmittelbare Problem behoben, da Objective-C die Arbeit für Sie erledigt, aber Sie sollten trotzdem die Speicherverwaltung überprüfen, da es zu 100% sicher ist, dass Sie weiterhin Probleme haben werden.

0

Es klingt dumm, aber auf Division durch Null überprüfen. Ich hatte den gleichen Fehler und der Grund war eine Division durch Null.