Search code examples
xcodereferenceios6retaincount

View object becoming nil abruptly - xcode


I have a View object becoming nil abruptly in my method.

I am not using ARC

no threading is involved


Whats happening is that 1st time i call that 1stmethod method everything works fine and the reference to the livescoreSettings is retained.

Next when i call 2ndmethod method also the livescoreSettings ref is retained but by the time the delegate method gets activated the reference of that variable is lost.. dont know why...

@interface XY {
    LiveScoreSettingsView * livescoreSettings; // initialisation in .h file inside    
}
@end

@implementation

// 1st method
- (void)1stmethod:(id) callingClass username:(NSString*)username {
    livescoreSettings=callingClass;   // retain count increases to 1 
    isLivescoresSettingsView = YES;

    //.... some code where the above livescoreSettings variables are not used ... //
}

// 2nd method  
- (void)2ndmethod:(id) callingClass username:(NSString*)username matchid:(NSString *)matchid  eventType:(NSString *) eventType  add:(NSString *) add {
    livescoreSettings=callingClass;
    isLivescoresSettingsView = YES;
    addEventToList = YES;

    //.... some code where the above livescoreSettings variables are not used ... //
}

// delegate method thats activated when the response comes 
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {
   // the block where the data is sent to a particular view to reload table 
   else if(isLivescoresSettingsView== YES || addEventToList == YES) {
    isLivescoresSettingsView=NO;
    addEventToList = NO;

     //.... some code where the above livescoreSettings variables are not used ... //

    if(success)
        NSLog(@"No Errors with retain count = %d ", [livescoreSettings retainCount]); 
    else
        NSLog(@"Error Error Error!!!");

    [livescoreSettings.tableView reloadData];

   // when **2ndmethod** is called there's no memory reference to  livescoreSettings, tableView delegate methods are not called which is obvious. But not sure why the retain count is reducing abruptly.
    }
}

@end

Solution

  • The issue is that you are not taking ownership of livescoreSetting that is being passed into 1stmethod or 2ndmethod. If you are not using ARC then you will need to retain it in those methods and release it in your dealloc method (simply assigning the instance to livescoreSetting does not increase the retain count when using MRR).

    Imagine if 1stmethod is called in this way:

    LivescoreSettingsView *view = [[LivescoreSettingsView alloc] init];
    [whateverItsCalled 1stmethod:view;         // (1)
    [view release];                            // (2)
    

    Then view is being assigned to whateverItsCalled.livescoreSetting at (1), but the retain count is 1. After (2) the retain count is 0, however whateverItsCalled.livescoreSetting is now a dangling pointer and I'm surprised you don't see messages like "message sent to deallocated object" rather than the errors you are seeing (I cannot see why it's being assigned to nil when ARC is not involved).

    To solve the problem, you need to synthesize your setter/getter methods for the instance variable by adding a @property for it. I prefer to name the instance variables using a leading underscore (_) to differentiate them from the setter/getter methods names; so:

    .h file:

    @interface WhateverItsCalled : NSObject
    {
        LiveScoreSettingsView *_livescoreSetting;
    }
    
    @property (retain, nonatomic, readwrite) LiveScoreSettingsView *livescoreSetting;
    

    .m file:

    @implementation WhateverItsCalled
    @synthesize livescoreSetting = _livescoreSetting;
    
    - (void)dealloc
    {
        self.livescoreSetting = nil;           // Release the object by assigning nil
        [super dealloc];
    }
    
    - (void)firstmethod:(id) callingClass username:(NSString*)username
    {
        self.livescoreSettings = callingClass;   // Note the use of self!
        isLivescoresSettingsView = YES;
    }
    
    - (void)secondmethod:(id)callingClass username:(NSString*)username matchid:(NSString *) matchid  eventType:(NSString *) eventType  add:(NSString *) add
    
    {
        self.livescoreSettings = callingClass;   // Note the use of self!
        isLivescoresSettingsView = YES;
        addEventToList = YES;
    }