App does not register changes to variables - really puzzled

Discussion in 'Mac Programming' started by kwfl, Jan 10, 2011.

  1. kwfl macrumors 6502

    Joined:
    Aug 20, 2007
    #1
    Hi there,

    I really have a very puzzling problem that driving me crazy. I am building a chess app for mac. Things were working fine, but now i dont know what changed to make this problem.

    The problem is that if i change a variable's value in a place (same class), when i access it from another method, it is not changed. Example if i change a BOOL value from NO to YES in method A and it will still show as NO in method B. Same with NSArray/NSMutableArray if i add an objet in a method it still shows count of zero in another method.

    Here is the code.

    Code:
    -(void)windowDidResize:(NSNotification *)notification
    {
    	self.resizeItemsViews = YES;
    	[self.splitView setPosition:[self.window frame].size.width-200 ofDividerAtIndex:0];
    	[self setNeedsDisplay: YES];
    }
    the drawRect method
    Code:
    - (void)drawRect:(NSRect)dirtyRect {
    	
    	if (self.resizeItemsViews) {
    		NSLog(@"self.resizeItemsViews = YES");
    	}
    	else {
    		NSLog(@"self.resizeItemsViews = NO");
    	}
    
        //Drawing Code
    }
    i also added an observeValueForKeyPath to see when self.resizeItemsViews changes
    Code:
    -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
    	if ([keyPath isEqualToString:@"resizeItemsViews"]) {
    		if (self.resizeItemsViews) {
    			NSLog(@"Observer self.resizeItemsViews = YES");
    		}
    		else {
    			NSLog(@"Observer self.resizeItemsViews = NO");
    		}
    	   }
    	}
    }
    This is what i get through my console when i resize the window (A sample). The first tow NOs are because i set self.resizeItemsViews to NO in the awakeFromNib method. Why twice?! the awakeFromNib is called twice. I dont know why!!! :mad:

    2011-01-11 01:58:25.399 Views[1457:a0f] Observer self.resizeItemsViews = NO
    2011-01-11 01:58:25.402 Views[1457:a0f] Observer self.resizeItemsViews = NO
    2011-01-11 01:58:25.475 Views[1457:a0f] drawRect self.resizeItemsViews = NO
    2011-01-11 01:58:28.290 Views[1457:a0f] Observer self.resizeItemsViews = YES
    2011-01-11 01:58:28.296 Views[1457:a0f] drawRect self.resizeItemsViews = NO
    2011-01-11 01:58:28.311 Views[1457:a0f] Observer self.resizeItemsViews = YES
    2011-01-11 01:58:28.313 Views[1457:a0f] drawRect self.resizeItemsViews = NO
    2011-01-11 01:58:28.324 Views[1457:a0f] Observer self.resizeItemsViews = YES
    2011-01-11 01:58:28.327 Views[1457:a0f] drawRect self.resizeItemsViews = NO
    2011-01-11 01:58:28.341 Views[1457:a0f] Observer self.resizeItemsViews = YES
    2011-01-11 01:58:28.344 Views[1457:a0f] drawRect self.resizeItemsViews = NO
    2011-01-11 01:58:28.354 Views[1457:a0f] Observer self.resizeItemsViews = YES
    2011-01-11 01:58:28.357 Views[1457:a0f] drawRect self.resizeItemsViews = NO
    2011-01-11 01:58:28.375 Views[1457:a0f] Observer self.resizeItemsViews = YES

    with NSMutableArray

    if i add an object in method A, count in method B is zero. However if i execute method A again i see count as 1 (two after adding another object) and yet again count zero in method B.
     
  2. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    awakeFromNib is being called twice most likely because you have two instances of this object being created from your nib. Double check your nib and code and make sure you don't have duplicate instances.

    You can confirm by in either awakeFromNib or init logging:
    Code:
    NSLog(@"init: %p", self);
    and you will probably see two of these with different hexadecimal values.

    You could also put a breakpoint in awakeFromNib to give you some hints as to where the second instance is being created from.
     
  3. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #3
    Probably not init. I have logged init for nib objects and found it being called twice. I cannot explain it, but by the init logging, it looks like two different objects are being created.
     
  4. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #4
    Having two instances means there is a 50% chance that resizeItemViews is set for the wrong object.
     
  5. kwfl thread starter macrumors 6502

    Joined:
    Aug 20, 2007
    #5
    Actually having two instances of the same object makes sense to me as the cause for this trouble.

    Here is the result after adding (NSLog(@"init: %p", self);) to my awakeFromNib method
    Clearly two instances of self. (Thanks for the tip).
    2011-01-11 15:53:32.174 Views[6744:a0f] init: 0x10050e650
    2011-01-11 15:53:32.178 Views[6744:a0f] Observer self.resizeItemsViews = NO
    2011-01-11 15:53:32.179 Views[6744:a0f] init: 0x10050ec70
    2011-01-11 15:53:32.180 Views[6744:a0f] Observer self.resizeItemsViews = NO
    2011-01-11 15:53:32.279 Views[6744:a0f] drawRect self.resizeItemsViews = NO

    I really dont mess with the Nib file in my class code. It must be in interface builder, as i changed a lot there before this problem arose. Thanks for your help, i will get back to you if i find the cause of this.
     
  6. kwfl thread starter macrumors 6502

    Joined:
    Aug 20, 2007
    #6
    Can anyone suggest why the awakeFromNib is called twice.
    i put the breakpoints and they give me no clue. Just at the end of the first cal of awakeFromNib, the method is called again. There is nothing in between.

    What are the things to look for in IB or in the code?

    Thanks
     
  7. kwfl thread starter macrumors 6502

    Joined:
    Aug 20, 2007
    #7
    One observation in my Nib file.

    Both my custom view and the Views App Delegate are referring to the same class. (the class that has the trouble).

    Is this the reason?
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    It's called once for each object. Since you have two objects, it's called twice.

    Again, log the object's self using %p in awakeFromNib, and you should see it coming from each object.

    I get the feeling you don't entirely understand the difference between a class (of which there's only one), and instances of a class (which may be many). A nib file stores instances of a class**. It does not contain a class, thought it obviously does contain the name of a class.


    You should probably look at how it's reaching awakeFromNib. Or how it's reaching init. You'll have to look at the stack backtrace to see how it gets there.

    If both objects are created from a path that originates in the loading of a nib, then you know both objects are created from information stored in the nib. If one originates in loading the nib and one originates in code you write that creates an object, then you know how each one got there.


    To track down where a nib-based object creation is coming from, try temporarily renaming the class that's being instantiated. Clean and build. If IB complains (and it may not), then go there and have it show you the complaint, which would be of a missing class. If IB doesn't complain, then run your build. It should crash. Then look at the stack backtrace and see where it is in loading the nib.


    ** Actually, it stores coded data for recreating an instance. It doesn't contain an actual runnable instance. But the coded data still represents an instance, not a class.
     
  9. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #9
    At the beginning of awakeFromNib, add

    NSLog (@"awakeFromNib: self = %@", self);

    Most likely your nib file has two objects of the same class. awakeFromNib is per object, not per class.
     
  10. kwfl thread starter macrumors 6502

    Joined:
    Aug 20, 2007
    #10
    Thanks for your help. Now i know i have two objects in the nib refering to the same class. I should move the reference of the custom view object to a separate class.
     

Share This Page