Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 08-17-2010, 04:38 AM   #1 (permalink)
Registered Member
 
Join Date: Aug 2010
Posts: 6
macz is on a distinguished road
Default Memory Problems with Array Property

Hi all,

I've got some problems to keep the values in an array-property:

There is an UITableViewController which has an property books:

Code:
@property (nonatomic, retain) NSArray *books;
In it's loadView method the UITableViewController requests some data from a webservice (which is a class by its own, referenced in the ApplicationDelegate). When the webservice has finished his asynchronous request he calls back a method on the UITableViewController, delivering a piece of XML:

Code:
- (void)didGetBooksForController:(GDataXMLElement *)returnNode {
	
	NSArray *booksXML = [returnNode elementsForName:@"item"];
	//NSLog(@"%@", returnNode);
	self.books = [NSArray array];
	for (GDataXMLElement *bookXML in booksXML) {
		NSLog(@"%@", bookXML);
		Book *aBook = [[Book alloc] initWithXML:bookXML];
		self.books = [self.books arrayByAddingObject:aBook];
		[aBook release];
	}
	[self.tableView reloadData];
}
All works fine - the returnNode XML holds the data I was looking for, the array holds the number of objects I expected.
The last line in the previous method initiates the UITableView to ask his delegate (my UITableViewController) to provide him with data for the cells:

Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    
	NSUInteger row = [indexPath row];
	NSUInteger section = [indexPath section];
	
	if (books != nil) {
		
		switch (section) {
			case 0: {
				Book *aBook = [self.books objectAtIndex:row] ;	
				cell.textLabel.text = aBook.mediatitle;
                                [aBook release];
				break;
			}
			case 1:
				cell.textLabel.text = @"Scenario";
				break;
			default:
				break;
		}
	}
    return cell;
}
but unfortunatly the property self.books seems to be gone!

I'am sure I've got some issues with my retainCount, but I can't figure out which variable to retain without leaving memory unreleased.
macz is offline   Reply With Quote
Old 08-17-2010, 05:14 AM   #2 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: London, UK
Posts: 1,050
wuf810 is on a distinguished road
Default

Not sure but shouldn't books be a mutable array?
wuf810 is offline   Reply With Quote
Old 08-17-2010, 05:45 AM   #3 (permalink)
Registered Member
 
Join Date: Aug 2010
Posts: 6
macz is on a distinguished road
Default

Quote:
Originally Posted by wuf810 View Post
Not sure but shouldn't books be a mutable array?
I had the same idea, but the result was disappoiting ...

Meanwhile I've got it working:

I retain the mediatitle property in the initWithXML: method after extracting its value from the XML.

I am not sure in doing this, cause allthough the XML is an autoreleased object, which doesn't survive the eventcycle, assigning it to the property mediatitle should retain it for the livetime of the book object.

Last edited by macz; 08-17-2010 at 05:58 AM.
macz is offline   Reply With Quote
Old 08-17-2010, 06:40 AM   #4 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: London, UK
Posts: 1,050
wuf810 is on a distinguished road
Default

Quote:
Originally Posted by macz View Post
I had the same idea, but the result was disappoiting ...

Meanwhile I've got it working:

I retain the mediatitle property in the initWithXML: method after extracting its value from the XML.

I am not sure in doing this, cause allthough the XML is an autoreleased object, which doesn't survive the eventcycle, assigning it to the property mediatitle should retain it for the livetime of the book object.
Yes that makes sense. Better still would be to create a class called books and create an instance of books (during the init assign the attributes you retrieved to instance variable) and then add the book object to your array.

M.
wuf810 is offline   Reply With Quote
Old 08-17-2010, 06:47 AM   #5 (permalink)
Registered Member
 
Join Date: Aug 2010
Posts: 6
macz is on a distinguished road
Default

Quote:
Originally Posted by wuf810 View Post
Yes that makes sense. Better still would be to create a class called books and create an instance of books (during the init assign the attributes you retrieved to instance variable) and then add the book object to your array.
M.
ehm - isn't that exactly what I am doing? I've got a class Book - in initWithXML I am assigning the xml-attributes to instance variables - finally I add the aBook-instance to my Array books.
macz is offline   Reply With Quote
Old 08-17-2010, 06:55 AM   #6 (permalink)
Registered Member
 
Join Date: Aug 2010
Posts: 6
macz is on a distinguished road
Default



Retaining the properties in the Book-class does the job only on first sight:

When I scroll a table-cell out of sight and back again (which invokes ..cellForRowAtIndexPath... again) my app crashes: no more books in the array!
macz is offline   Reply With Quote
Old 08-17-2010, 07:02 AM   #7 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: London, UK
Posts: 1,050
wuf810 is on a distinguished road
Default

Quote:
Originally Posted by macz View Post
ehm - isn't that exactly what I am doing? I've got a class Book - in initWithXML I am assigning the xml-attributes to instance variables - finally I add the aBook-instance to my Array books.
oops sorry yes, I wasn't concentrating.
wuf810 is offline   Reply With Quote
Old 08-17-2010, 07:05 AM   #8 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: London, UK
Posts: 1,050
wuf810 is on a distinguished road
Default

Quote:
Originally Posted by macz View Post


Retaining the properties in the Book-class does the job only on first sight:

When I scroll a table-cell out of sight and back again (which invokes ..cellForRowAtIndexPath... again) my app crashes: no more books in the array!
I've lost track of the changes you've made...do you want to re post the latest code.
wuf810 is offline   Reply With Quote
Old 08-17-2010, 08:14 AM   #9 (permalink)
Registered Member
 
Join Date: Aug 2010
Posts: 6
macz is on a distinguished road
Default

Quote:
Originally Posted by wuf810 View Post
I've lost track of the changes you've made...do you want to re post the latest code.
thank you for your engagement - but finally I diceded to rethink my design.
All in all it boils to down to one question.

This is the initializer of my Book class:

Code:
- (id)initWithXML:(GDataXMLElement *)theXML {
	
    self = [super init];
    if (self) {
		NSArray *mediatitles = [theXML elementsForName:@"mediatitle"];
		if (mediatitles.count > 0) {
			GDataXMLElement *anTitle = (GDataXMLElement *) [mediatitles objectAtIndex:0];
			self.mediatitle  = anTitle.stringValue;
			[self.mediatitle retain];
		}
    }

	
    return self;
}
Why do I have to retain mediatitle?
I thought invoking the synthesized setter would do this for me (and btw force me to release all my properties in the dealloc method)
macz is offline   Reply With Quote
Old 08-17-2010, 08:28 AM   #10 (permalink)
Registered Member
 
Join Date: Sep 2008
Location: London, UK
Posts: 1,050
wuf810 is on a distinguished road
Default

Quote:
Originally Posted by macz View Post
thank you for your engagement - but finally I diceded to rethink my design.
All in all it boils to down to one question.

This is the initializer of my Book class:

Code:
- (id)initWithXML:(GDataXMLElement *)theXML {
	
    self = [super init];
    if (self) {
		NSArray *mediatitles = [theXML elementsForName:@"mediatitle"];
		if (mediatitles.count > 0) {
			GDataXMLElement *anTitle = (GDataXMLElement *) [mediatitles objectAtIndex:0];
			self.mediatitle  = anTitle.stringValue;
			[self.mediatitle retain];
		}
    }

	
    return self;
}
Why do I have to retain mediatitle?
I thought invoking the synthesized setter would do this for me (and btw force me to release all my properties in the dealloc method)
You are correct, you shouldn't need to. Sorry, I know that isn't much help…
wuf810 is offline   Reply With Quote
Old 08-17-2010, 08:49 AM   #11 (permalink)
Registered Member
 
Join Date: Aug 2010
Posts: 6
macz is on a distinguished road
Default

Quote:
Originally Posted by wuf810 View Post
You are correct, you shouldn't need to. Sorry, I know that isn't much help…
thanks mate - you made my day!
macz is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 359
5 members and 354 guests
freewind, givensur, linkmx, Newbie123, PlutoPrime
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,657
Threads: 94,118
Posts: 402,894
Top Poster: BrianSlick (7,990)
Welcome to our newest member, jenniead38
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 12:50 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0