Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 神奇记录将大量数据保存到数据库_Ios_Objective C_Core Data_Magicalrecord - Fatal编程技术网

Ios 神奇记录将大量数据保存到数据库

Ios 神奇记录将大量数据保存到数据库,ios,objective-c,core-data,magicalrecord,Ios,Objective C,Core Data,Magicalrecord,我正在使用神奇的记录将大量数据保存到我的数据库中。我想把它保存在后台,但它冻结了用户界面。我正在使用 [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { } completion:^(BOOL success, NSError *error) { }]; 所以它不应该阻塞UI。但我发现,出于某些原因,它使用主线程来合并更改或类似的内容。如果有人能提出一个解决方案,使这项工作更有效率,我将不

我正在使用神奇的记录将大量数据保存到我的数据库中。我想把它保存在后台,但它冻结了用户界面。我正在使用

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
    } completion:^(BOOL success, NSError *error) {
    }];
所以它不应该阻塞UI。但我发现,出于某些原因,它使用主线程来合并更改或类似的内容。如果有人能提出一个解决方案,使这项工作更有效率,我将不胜感激

我正在使用的代码:

- (void)saveRidesForUser:(User *)user fromResponseData:(id)responseData
{

    if (![[[responseData valueForKey:@"rides"] class] isSubclassOfClass:[NSArray class]]) {
        return;
    }
    NSArray *rides = [responseData valueForKey:@"rides"];

    if (!rides)
        return;

    NSMutableArray *photoCacheArray = [[NSMutableArray alloc] init];

    [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {

        User *rideUser = [user MR_inContext:localContext];

        for (NSDictionary *rideDictionary in rides) {

                Ride *ride = [Ride MR_createEntityInContext:localContext];
                ride.title = ([rideDictionary objectForKey:@"title"]) ? [rideDictionary valueForKey:@"title"] : @"";

                NSNumber *rideTimeStamp =[rideDictionary objectForKey:@"start_date"];
                if (rideTimeStamp)
                    ride.startDate = [NSDate dateWithTimeIntervalSince1970:[rideTimeStamp doubleValue]];

                NSNumber *rideEndTimeStamp =[rideDictionary objectForKey:@"end_date"];
                if (rideEndTimeStamp)
                    ride.endDate = [NSDate dateWithTimeIntervalSince1970:[rideEndTimeStamp doubleValue]];

                ride.serverID = [NSNumber numberWithInt:[[rideDictionary objectForKey:@"id"] intValue]];
                ride.isPopular = [NSNumber numberWithBool:NO];

                if ([rideDictionary objectForKey:@"intervals"]) {
                    NSArray *intervals = [rideDictionary objectForKey:@"intervals"];

                    for (NSDictionary *intervalDictionary in intervals) {

                        RideInterval *interval = [RideInterval MR_createEntityInContext:localContext];

                        interval.startDate = [NSDate dateWithTimeIntervalSince1970:[[intervalDictionary objectForKey:@"start_date"] integerValue]];
                        interval.endDate = [NSDate dateWithTimeIntervalSince1970:[[intervalDictionary objectForKey:@"end_date"] integerValue]];

                        interval.ride = ride;

                        if ([intervalDictionary objectForKey:@"points"] && ![[[intervalDictionary objectForKey:@"points"] class] isSubclassOfClass:[NSString class]]) {
                            NSArray *points = [intervalDictionary objectForKey:@"points"];

                            for (NSDictionary *pointDict in points) {

                                NSDictionary *pointDictionary = [pointDict dictionaryByReplacingNullsWithStrings];

                                RidePoint *point = [RidePoint MR_createEntityInContext:localContext];
                                point.timestamp = [NSDate dateWithTimeIntervalSince1970:[[pointDictionary objectForKey:@"timestamp"] integerValue]];

                                point.latitude = [NSNumber numberWithDouble:[[pointDictionary objectForKey:@"latitude"] doubleValue]];
                                point.longitude = [NSNumber numberWithDouble:[[pointDictionary objectForKey:@"longitude"] doubleValue]];
                                point.distanceFromPrevious = [NSNumber numberWithDouble:[[pointDictionary objectForKey:@"distance_from_previous"] doubleValue]];
                                point.interval = interval;
                            }
                        }
                    }
                }

                if ([rideDictionary valueForKey:@"photos"] && [[[rideDictionary valueForKey:@"photos"] class] isSubclassOfClass:[NSArray class]]) {
                    NSArray *photos = [rideDictionary objectForKey:@"photos"];

                    for (NSDictionary *photoDict in photos) {

                        NSDictionary *photoDictionary = [photoDict dictionaryByReplacingNullsWithStrings];
                        RidePhoto *photo = [RidePhoto MR_createEntityInContext:localContext];

                        photo.caption = [photoDictionary valueForKey:@"caption"];

                        NSNumber *timeStamp =[photoDictionary objectForKey:@"timestamp"];
                        if (timeStamp)
                            photo.timestamp = [NSDate dateWithTimeIntervalSince1970:[timeStamp doubleValue]];

                        photo.locationLatitude = [NSNumber numberWithDouble:[[photoDictionary objectForKey:@"location_latitude"] doubleValue]];
                        photo.locationLongitude = [NSNumber numberWithDouble:[[photoDictionary objectForKey:@"location_longitude"] doubleValue]];
                        photo.serverPath = [photoDictionary objectForKey:@"url"];
                        photo.imagePath = [NSString getUUID];
                        photo.ride = ride;

                        [photoCacheArray addObject:photo];
                    }
                }

                ride.user = rideUser;
            }

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

        [[NSNotificationCenter defaultCenter] postNotificationName:kLTRideServise_RoutesDownloadedNotification object:nil userInfo:nil];

    }];

}

提前感谢您的帮助

您是否将MR_defaultContext用于所有其他主线程任务

我使用saveWithBlock:method进行后台保存,MR_defaultContext用于主线程操作,效果很好。据我所知,MagicalRecord正在保存操作结束时将localContext与defaultContext合并

示例代码:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.0 * NSEC_PER_SEC),      
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
        // your loop here in background thread
    } completion:^(BOOL success, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            // completion on main thread
        });
    }];
});

[[NSNotificationCenter defaultCenter]postNotificationName:kLTRideServise_Routes下载通知对象:nil用户信息:nil]

==>检查完成时正在进行的处理。此通知在主线程上调用,可能是因为您正在进行大量处理,这使得主线程处于繁忙状态,导致UI冻结

还要检查您是否已从任何上下文中注册了NSManagedObjectContextDidSaveNotification,并查看您是否正在那里进行任何处理。

我正在使用

[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:aCallback]; [[NSManagedObjectContext MR_defaultContext]MR_保存到持久存储并完成:aCallback]; 将上下文保存到数据库中

是这样记录的

/// \brief Asynchronously save changes in the current context all the way back to the persistent store /// \param completion Completion block that is called after the save has completed. The block is passed a success state as a `BOOL` and an `NSError` instance if an error occurs. Always called on the main queue. /// \discussion Executes asynchronous saves on the current context, and any ancestors, until the changes have been persisted to the assigned persistent store. The completion block will always be called on the main queue. ///\brief异步保存当前上下文中的更改,一直保存到持久存储 ///\param完成块,在保存完成后调用。如果发生错误,则会将成功状态作为'BOOL'和'NSError'实例传递给块。始终在主队列上调用。 ///\discussion在当前上下文和任何祖先上执行异步保存,直到更改被持久化到指定的持久存储。将始终在主队列上调用完成块。
这对我来说很好,没有冰冻。

是的,我就是这样做的。我正在保存相当多的数据,这可能是问题所在吗?检查UI何时开始冻结-在“for”循环期间、循环之后或整个保存块之后。UI在for循环之后立即冻结。关于如何解决这个问题有什么想法吗?我已经为您添加了带有GCD的示例代码。这将完全消除流程中的冻结。不幸的是,情况完全相同。我已经读到saveWithBlock不应该这样使用。不管怎么说,我已经试过了,但没有什么改变。还有其他解决办法吗?