持久化NSMUtablearray,它是Core Data Entity的属性

时间:2010-10-04 13:47:46

标签: iphone objective-c ios ipad ios4

@interface Week : NSManagedObject { 

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

@end

我正在从服务器读取XML文件并将vales放在上面的实体中。因为WEEK可以读取多个书籍,所以它存储在MutableArray中。我使 * book 可以转换在我的 .xcdatamodel 文件中。

我的解析器看起来像这样解析并初始化周实体

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]);
   }

这样存储正常,因为我从Coredata获取上述值并存储在 NSMutableArray“weekArray”**中以显示在** UITableView 中。

我的程序在以下两个函数中崩溃,崩溃点在两个函数之间切换...奇怪!!!

- (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;
}

*请告诉我我在哪里做错了?我在我的解析器中存储NSMutableArray 书的方式是否有问题 NSManagedObject *object = (NSManagedObject *)[weekArray objectAtIndex:indexPath.row]; 线 因为我的NSLog不会在 indexPath.row 行下面打印。

我的获取功能

- (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];  
} 

1 个答案:

答案 0 :(得分:0)

看起来它可能是一个“过度释放的错误”。在你的获取方法中,你有:

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

使用fetch结果的可变副本初始化'mutableFetchResults'数组。然后指定该数组应该自动释放(意味着它将在可能时释放)。

然后使用以下命令将“mutableFetchResults”分配给类的属性:

self.weekArray = mutableFetchResults;

由于您已将此属性声明为“保留”,因此当您将“mutableFetchResults”指定给此属性时,您的类将保留该属性。现在,通过保留它,其他东西声称拥有了这个数组,之前的'autorelease'可以免费发送'release'消息。在这一点上,一切都很好,因为你的所有保留和释放是平衡的。但是,在下一行中,您将使用以下命令再次显式释放它:

[mutableFetchResults release];

这是不必要的,因为它已经被'autorelease'释放了。这种“过度释放”的结果是分配给'self.weekArray'的引用现在可能指向内存中的其他随机对象 - 这可能是您尝试访问数组时应用程序崩溃的原因