views:

50

answers:

3

Hi all,

I'm facing a strange problem with NSUsrDefaults. Whenever I'm fetching the data from NSUserDefaults, it's getting populated temporarily. I'm fetching it into viewDidLoad where it's fetched.

-(void)viewDidLoad{
companies = [NSMutableArray array];
oldCompanies = [[NSUserDefaults standardUserDefaults] arrayForKey:@"companyData"];
if( companies )
{
    for( NSData *data in oldCompanies )
    {
        companyObj = (Company*) [NSKeyedUnarchiver unarchiveObjectWithData:data];
        [companies addObject:companyObj];
    }
}
}

But outside viewDidLoad, whenever I try to access the data, the array "oldCompanies" as well as "companies" are shown "nil".

EDIT: I'm encoding my Company object in a class which subclasses NSCoding like shown below but not allocating or retaining the properties anywhere. Can this be the catch?

- (void)encodeWithCoder:(NSCoder *)encoder
{
//Encode properties, other class variables, etc
[encoder encodeObject:self.companyId forKey:@"id"];
[encoder encodeObject:self.companyTitle forKey:@"title"];
[encoder encodeObject:self.companyImage forKey:@"image"];
}

- (id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if( self != nil )
{
    //decode properties, other class vars
    self.companyId = [decoder decodeObjectForKey:@"id"];
    self.companyTitle = [decoder decodeObjectForKey:@"title"];
    self.companyImage = [decoder decodeObjectForKey:@"image"];
}
return self;
 }

Can anybody please help?

Thanx in advance.

+1  A: 

+array creates an autoreleased array - if you want to take ownership of it per the memory management rules then you need to retain it:

[companies retain];

Or create it so that it isn't autoreleased:

companies = [[NSMutableArray alloc] init];

Or, better, let declared properties do that for you:

// interface, property declaration:
@property(retain, readwrite) NSMutableArray *companies;

// implementation:
@synthesize companies;

// ... using it:
self.companies = [NSMutableArray array];
Georg Fritzsche
It's not working even after retain. Is it something related to NSUserDefaults memory management?
neha
@neha: What does *"not working"* mean? Is it still `nil`? Empty? Does the app crash? Is your mouse emitting purple smoke?
Georg Fritzsche
@Georg Yes, it's still nil.
neha
@neha: If its still `nil` it either was never set or overwritten afterwards. Did you check that `-viewDidLoad` is invoked first, e.g. via break-points or traces? Are you sure nothing else overwrites it afterward?
Georg Fritzsche
@Georg: I'm going through all the breakpoints, viewDidLoad is invoked first and there's not a single release in the class. P.S. I'm declaring and allocating the variables in this class itself.
neha
My NSUserDefaults are all set with the values but persisting the fetched values is what I'm failing at. Is there any "NSUserDefaults Memory Managment Guide" which I can refer to?
neha
@neha: The user defaults do not behave differently in that regard, there is some other problem.
Georg Fritzsche
@Georg: Thanx for your patience. Can you please check my edited question, I wanted to know wheather encoding the object properties the way I'm doing is right or not.
neha
@neha: If those properties are declared as `retain` or `copy` that should be fine. Have you tried to `NSLog()` *a)* `oldCompanies` directly after getting it from the user defaults and b) `companyObj` directly after unarchiving it? Is either of them `nil` or empty?
Georg Fritzsche
+1  A: 

You are not retaining the array, when you dont do an alloc, or a retain when instatiating an object you get an autoreleased object, in your example companies is autoreleased and is why you cant access it anymore at a later point you should either alloc it [[NSMutableArray alloc] init] or retain it [NSMutableArray array] retain]...either way refer to memory managment guide to learn about objective-c memory managment memory managment ref

Daniel
Even after _companies = [[NSMutableArray alloc] init]; [_companies retain]; array is nil outside viewDidLoad. Is it something related to NSUserDefaults memory management?
neha
u dont do both, you do one or the other, either way you must be doing something wrong
Daniel
A: 

Are you trying to access the data before the view is loaded?

Objective-C doesn't reset your pointers for you. If the array isn't "persisted", then the pointer will point to garbage.

tc.