保存一对多实体时的魔法记录异常

时间:2014-06-29 09:11:30

标签: xcode exception ios7 one-to-many magicalrecord

在我的新App中我有Core Data和Magical Record,这就是db:

的结构

这是与实体NEWS对应的类:

@class SMCategories;

@interface SMNews : NSManagedObject

@property (nonatomic, retain) NSNumber * wpId;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSString * content;
@property (nonatomic, retain) NSString * url;
@property (nonatomic, retain) NSString * thumbnailUrl;
@property (nonatomic, retain) NSString * thumbnailFile;
@property (nonatomic, retain) NSDate * date;
@property (nonatomic, retain) SMCategories *category;

这是与实体CATEGORIES:

对应的类
@interface SMCategories : NSManagedObject

@property (nonatomic, retain) NSNumber * wpId;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSDate * lastUpdate;
@property (nonatomic, retain) NSSet *news;
@end

@interface SMCategories (CoreDataGeneratedAccessors)

- (void)addNewsObject:(NSManagedObject *)value;
- (void)removeNewsObject:(NSManagedObject *)value;
- (void)addNews:(NSSet *)values;
- (void)removeNews:(NSSet *)values;

这是我用来在循环内保存应保存在实体CATEGORIES中的所有数据的函数:

- (void)saveUpdateCategories:(NSString *)result {

    NSDictionary *tmpCategories = [result objectFromJSONString];
    NSArray *categoriesList = [tmpCategories objectForKey:@"categories"];
    NSDictionary *singleCategory;

    NSPredicate * filter = [[NSPredicate alloc] init];

    for(int i = 0; i < [categoriesList count];i++) {
        singleCategory = [categoriesList objectAtIndex:i];
        filter = [NSPredicate predicateWithFormat:@"wpId == %@",[singleCategory objectForKey:@"id"]];
        SMCategories *checkCategory = [SMCategories MR_findFirstWithPredicate:filter];

        [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
            SMCategories *categoryToAdd;

            if (checkCategory == nil) {
                categoryToAdd = [SMCategories MR_createEntityInContext: localContext];
            } else {
                categoryToAdd = checkCategory;
            }

            categoryToAdd.name = [singleCategory objectForKey:@"name"];
            categoryToAdd.wpId = [currentUtils stringToNumber:[singleCategory objectForKey:@"id"]];
            categoryToAdd.lastUpdate = [currentUtils stringToDate:@"01/01/2000 00:00:01" formatted:@"dd/MM/yyyy HH:mm:ss"];
            categoryToAdd.news = nil;
        } completion:^(BOOL success, NSError *error) {
            if (i == [categoriesList count] - 1) {
                [progressWheel stopAnimating];
                NSMutableDictionary *tmpOptions = [[NSMutableDictionary alloc] init];
                tmpOptions = [currentUtils getDictionaryPlistFile:@"options.plist" path:[currentUtils getMainLocalPath]];
                [tmpOptions setObject:[NSDate date] forKey:@"lastCategoriesUpdates"];
                [currentUtils saveDictionaryPlistFile:tmpOptions fileName:@"options.plist" path:[currentUtils getMainLocalPath]];
                [menuButton setEnabled:YES];

                if (categoryToLoadPassed == nil)
                categoryToLoadPassed = [SMCategories MR_findFirstByAttribute:@"name" withValue:DEFAULT_CATEGORY];

                [self downloadNewsOfCategory:categoryToLoadPassed];
            }
        }];

    }

}

这部分代码也适用。

这是我用来在另一个循环中保存应该插入实体NEWS的所有数据的函数。

-(void) saveNewsOfCategory:(SMCategories *)category resultToSave: (NSString *) result {

    NSDictionary *tmpNews = [result objectFromJSONString];
    NSArray *newsList = [tmpNews objectForKey:@"posts"];
    NSDictionary *singleNew;

    NSPredicate * filter = [[NSPredicate alloc] init];

    for(int i = 0; i < [newsList count];i++) {
        singleNew = [newsList objectAtIndex:i];
        filter = [NSPredicate predicateWithFormat:@"wpId == %@",[singleNew objectForKey:@"id"]];
        SMNews *checkNew = [SMNews MR_findFirstWithPredicate:filter];

        [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {

            SMNews *newToAdd;
            if (checkNew == nil) {
                newToAdd = [SMNews MR_createEntityInContext: localContext];
            } else {
                newToAdd = checkNew;
            }

            newToAdd.category = category;
            newToAdd.title = [singleNew objectForKey:@"title"];
            newToAdd.content = [singleNew objectForKey:@"content"];
            newToAdd.wpId = [currentUtils stringToNumber:[singleNew objectForKey:@"id"]];
            newToAdd.date = [currentUtils stringToDate:[singleNew objectForKey:@"date"] formatted:@"yyyy-MM-dd HH:mm:ss"];
            newToAdd.url = [NSString stringWithFormat:@"%@?p=%@",WEBSITE,[singleNew objectForKey:@"id"]];
            newToAdd.thumbnailFile = nil;
            newToAdd.thumbnailUrl = [singleNew objectForKey:@"image"];
        } completion:^(BOOL success, NSError *error) {
            if (i == [newsList count] - 1) {

                [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {

                    category.lastUpdate = [NSDate date];

                } completion:^(BOOL success, NSError *error) {

                    [progressWheel stopAnimating];
                    [currentTable reloadData];
                }];

            }
        }];

    }

}

此处它在行

旁边抛出异常EXT_BAD_ACCESS
newToAdd.category = category;

类别作为相应函数的参数之一传递。

正如您所理解的那样,我有2个与一对多关系的entitis类别和新闻。 首先,我下载所有类别,当用户想要下载特定类别的所有新闻时,我将它们存储到CATEGORIES实体中我将其下载并与第二个函数一起存储到新闻实体中,将第二个函数传递到第二个函数中这些特定新闻的类别作为我的功能的参数。 如果删除该行,则所有新闻都正确存储在数据库中,但它们与任何cateogries无关。

我做错了什么?

1 个答案:

答案 0 :(得分:0)

以下行引发异常,因为我将实体保存在新线程中。

newToAdd.category = category;

所以使用单例类来获取类别并以这种方式设置特定的localcontex

SMCategories *currentCategory = [[DataManager getInstance] getCurrentCategory];

newsToAdd.category = [currentCategory MR_inContext:localContext];

现在一切正常。