NSObject release destroys local copy of object's data
- by Spider-Paddy
I know this is something stupid on my part but I don't get what's happening. I create an object that fetches data & puts it into an array in a specific format, since it fetches asynchronously (has to download & parse data) I put a delegate method into the object that needs the data so that the data fetching object copies it's formatted array into an array in the calling object. The problem is that when the data fetching object is released, the copy it created in the caller is being erased, code is:
In .h file
@property (nonatomic, retain) NSArray *imagesDataSource;
In .m file
// Fetch item details
ImagesParser *imagesParserObject = [[ImagesParser alloc] init:self];
[imagesParserObject getArticleImagesOfArticleId:(NSInteger)currentArticleId];
[imagesParserObject release] <-- problematic release
// Called by parser when images parsing is finished
-(void)imagesDataTransferComplete:(ImagesParser *)imagesParserObject
{
self.imagesDataSource = [ImagesParserObject.returnedArray copy]; // copy array to local variable
// If there are more pics, they must be assembled in an array for possible UIImageView animation
NSInteger picCount = [imagesDataSource count];
if(picCount > 1) // 1 image is assumed to be the pic already displayed
{
// Build image array
NSMutableArray *tempPicArray = [[NSMutableArray alloc] init]; // Temp space to hold images while building
for(int i = 0; i < picCount; i++)
{
// Get Nr from only article in detailDataSource & pic name (Small) from each item in imagesDataSource
NSString *picAddress = [NSString stringWithFormat:@"http://some.url.com/shopdata/image/article/%@/%@", [[detailDataSource objectAtIndex:0] objectForKey:@"Nr"], [[imagesDataSource objectAtIndex:i] objectForKey:@"Small"]];
NSURL *picURL = [NSURL URLWithString:picAddress];
NSData *picData = [NSData dataWithContentsOfURL:picURL];
[tempPicArray addObject:[UIImage imageWithData:picData]];
}
imagesArray = [tempPicArray copy]; // copy makes immutable copy of array
[tempPicArray release];
currentPicIndex = 0; // Assume first pic is pic already being shown
}
else
imagesArray = nil; // No need for a needless pic array
// Remove please wait message
[pleaseWaitViewControllerObject.view removeFromSuperview];
}
I put in tons of NSLog lines to keep track of what was going on & self.imagesDataSource is populated with the returned array but when the parser object is released self.imagesDataSource becomes empty. I thought
self.imagesDataSource = [ImagesParserObject.returnedArray copy];
is supposed to make an independant object, like as if it was alloc, init'ed, so that self.imagesDataSource is not just a pointer to the parser's array but is it's own array. So why does the release of the parser object clear the copy of the array. (I checked & double checked that it's not something overwriting self.imagesDataSource, commenting out [imagesParserObject release] consistently fixes the problem)
Also, I have exactly the same problem with self.detailDataSource which is declared & populated in the exact same way as self.imagesDataSource
I thought that once I call the parser I could release it because the caller no longer needs to refer to it, all further activity is carried out by the parser object through it's delegate method, what am I doing wrong?