Accessing properties of custom object causes crash but no error in debugger

Discussion in 'iOS Programming' started by CaroD, Nov 19, 2010.

  1. CaroD macrumors newbie

    Joined:
    Nov 19, 2010
    #1
    Hi,

    I've got a problem with my app crashing in the simulator without any error message.

    Basically I have a view which reads in an XML, parses it then on a button click calls another view which displays some of the parsed information. I'm an ActionScript developer so I took the same approach I would have taken in Flash to save the parsed information - I created a custom object with a property for each piece of information then put all the custom objects in an array.

    -- Code for the custom object:
    Code:
    #import "Posizione.h"
    
    
    @implementation Posizione
    
    @synthesize collezione;		// will be set by calling object
    @synthesize path;			// ditto
    @synthesize img;
    @synthesize titolo;
    @synthesize tipomanichini;
    @synthesize tipologia;
    @synthesize xNode;			
    @synthesize descrizione;
    
    
    - (id)initWithNode:(CXMLElement *)node {
        // Assign self to value returned by super's designated initializer
        // Designated initializer for NSObject is init
    	NSLog(@"init posiizione");
        self = [super init];
    	xNode = node;
    	titolo = [[xNode attributeForName:@"titolo"] stringValue];
    	img = [NSString stringWithFormat:@"%@/%@", path, [[xNode attributeForName:@"img"] stringValue]];
    	tipologia = [[xNode attributeForName:@"tipologia"] stringValue];
    	tipomanichini = [[xNode attributeForName:@"tipomanichini"] stringValue];
    	descrizione = [xNode stringValue];
    	[self sayHello];
        [self sayHelloTitle];
    	return self;
    }
    
    -(void)sayHelloTitle{
    	NSLog(@"hello %@", self.titolo);
    }
    
    -(void)sayHello{
    	NSLog(@"hello");
    }
    
    - (void)dealloc {
    	[collezione release];
    	[path release];
    	[img release];
    	[titolo release];
    	[tipomanichini release];
    	[tipologia release];
    	[xNode release];
    	[descrizione release];
        [super dealloc];
    }
    
    @end
     
    This works fine and the object is created as expected.

    When I pass the array to the second view, it can read the objects, but as soon as I try to access a property the app crashes with no error message in the debugger.
    Here's the piece of code that accesses the object and the various different things I've tried to access it with their respective results:

    Code:
    for (int i=0; i<[nArray count]; i++) {
    	Posizione *pos = [nArray objectAtIndex:i];
    	[pos sayHello];				// works 
            [pos sayHelloTitle];		// causes an exit with no error
    	NSLog(@"pos: %@", [nArray objectAtIndex:i]);		// Returns <Posizione: 0x64787b0>
    	//NSLog(@"pos img: %@", pos.img);					// causes crash with no error
    }
     
    Is my approach totally off? Should I be writing this object to disk or something? I suspect the crash is due to some sort of memory violation but without an error message I'm stumped. Or would I be better off just saving all this information in a dictionary?

    Thanks in advance,

    Caroline.
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    Caroline,

    You need to think carefully about the memory management rules and how you are setting properties.

    If we have a property x then this code:

    Code:
    x=y;
    
    simply sets the value of x to y. It does not call any setter. If y is autoreleased it does not get retained.

    If we use
    Code:
    self.x = y;
    
    then the syntactic sugar of properties gets expanded to

    Code:
    [self setX:y];
    
    So the accessor is called and (assuming the property is set to retain) then y is retained as expected.

    Now that we understand the theory we look at your specific problem:

    Code:
    titolo = [[xNode attributeForName:@"titolo"] stringValue];
    
    We are setting titolo directly, not via the synthesized accessor, to an autoreleased object (as per the standard memory management rules) and not retaining it. So when you then try and use that object in sayHelloTitle you have a pointer to a non-existent object and your code, as expected, crashes.
     
  3. CaroD thread starter macrumors newbie

    Joined:
    Nov 19, 2010
    #3
    Thank you so much! That solved it. I am officially a muppet, I should have spotted that!
     
  4. seepel macrumors 6502

    seepel

    Joined:
    Dec 22, 2009
    #4
    In cases like this I usually turn break points on so I can get a stack trace, though admittedly this only helps about 30% of the time.
     

Share This Page