views:

29

answers:

1
@interface Week : NSManagedObject { 

}
@property (nonatomic, retain) NSNumber *weekID;
@property (nonatomic, retain) NSString *top;
@property (nonatomic, retain) NSString *summary1;
@property (nonatomic, retain) NSMutableArray *book;

@end

I'm reading XML file from server and putting vales in above entity.Since Books to be read for that WEEK can be multiple so it is stored in MutableArray.I made *book to be transformable in my .xcdatamodel file.

My parser looks like this which parse and initialize above Week entity.

if ([currentTag isEqualToString:@"book"]) {
   NSString *USGSWebLink = [currentElementValue1 stringByStandardizingPath] ;   
   [week.book addObject:USGSWebLink];
   [week setBook:week.book];
   NSError *error;
   if (![self.managedObjectContext save:&error]) {
    NSLog(@"%@", [error domain]);
   }

This is storing fine because I fetch the above value from Coredata and store in NSMutableArray "weekArray"**to be displayed in **UITableView.

My program crashes in below two functions and point of crash toggles between below 2 functions...strange!!!

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    **//sometimes program crashes at this point**
     return [weekArray count]; 
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

 NSManagedObject *object = (NSManagedObject *)[weekArray objectAtIndex:indexPath.row];
    **// program crash at the above line.** 
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    }

 cell.textLabel.text = [object valueForKey:@"top"];
 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    // Set up the cell
    return cell;
}

*Pls tell me where I'm doing wrong ? Is it problem in the way I'm storing NSMutableArray book in my parser or NSManagedObject *object = (NSManagedObject *)[weekArray objectAtIndex:indexPath.row]; line Because my NSLog does not print below indexPath.row line.

My fetch function is:

- (void)fetchRecords {   

 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Week" inManagedObjectContext:appDelegate.managedObjectContext];   

 NSFetchRequest *request = [[NSFetchRequest alloc] init];  
    [request setEntity:entity];   //NSLog(@"fetchRecords = %@",appDelegate.managedObjectContext );

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"weekID" ascending:YES];  
 NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];  
    [request setSortDescriptors:sortDescriptors];  
    [sortDescriptor release];   

    NSError *error;     
 NSMutableArray *mutableFetchResults = [[[managedObjectContext executeFetchRequest:request error:&error] mutableCopy] autorelease] ;
    if (!mutableFetchResults) {  
    }   
 if (mutableFetchResults == nil) {
  NSLog(@"week fetch failed");
 } 
 self.weekArray = mutableFetchResults; NSLog(@"weekArray = %@",weekArray);
    [mutableFetchResults release];  
 [request release];  
} 
A: 

Looks like it might be an 'over-releasing bug'. In your fetch method you have:

NSMutableArray *mutableFetchResults = 
    [[[managedObjectContext executeFetchRequest:request 
                                          error:&error] mutableCopy] autorelease] ;

Which initialises the 'mutableFetchResults' array with a mutable copy of the result of the fetch. You then specify that this array should be autoreleased (meaning it will be released when it can be).

You then assign the 'mutableFetchResults' to a property of your class with:

self.weekArray = mutableFetchResults;

As you've declared this property as 'retain', when you assign 'mutableFetchResults' to this property your class will retain it. Now that something else has claimed ownership of this array by retaining it, the earlier 'autorelease' is free to send the 'release' message. At this point everything is fine as all your retains and releases are balanced. However, on the next line you explicitly release it again with:

[mutableFetchResults release];

This is unnecessary as it'll already have been released by the 'autorelease'. The result of this 'over-release' is that the reference assigned to 'self.weekArray' may now be pointing to some other random object in memory - which may well be the reason that your application is crashing when you try to access the array.

Jake
Thanks a lot "Jake". My program is working absolutely fine after removing "[mutableFetchResults release];" . I could not have possibly figured it out myself which you did.
Ravi