从关系中删除孤立对象

Posted

技术标签:

【中文标题】从关系中删除孤立对象【英文标题】:Deleting orphaned objects from relationship 【发布时间】:2014-07-24 20:55:12 【问题描述】:

我正在尝试使用 addFetchRequestBlock 方法从我正在进行的 API 调用中删除孤立对象。但是,我希望它删除的对象是与主要对象的各种关系中的对象。

最外面的对象是Day 对象,它有很多FoodEntry 对象。

API 调用/nutrition/days/2014-07-14

RKManagedObjectRequestOperation *operation = [[RKObjectManager sharedManager] appropriateObjectRequestOperationWithObject:nil method:RKRequestMethodGET path:[NSString stringWithFormat:@"nutrition/days/%@", dateFormatted] parameters:nil];

[operation setDeletesOrphanedObjects:YES];

[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) 
    self.day = (Day *)mappingResult.firstObject;
 failure:^(RKObjectRequestOperation *operation, NSError *error) 
    failure([operation decodeErrors]);
];

[RKObjectManager.sharedManager enqueueObjectRequestOperation:operation];

结果:


 "day": 
    "date": "2014-07-24",
        "food_entries": [
            
                "id": "53d14b973861330009de0300",
                "consumed_on": "2014-07-24",
                "food_id": 36394,
                "serving_id": 34187,
                "quantity": 1,
                "name": "Waffle",
                "brand": null,
                "description": "1 cup slices",
                "meal_type": "breakfast",
                "calories": 25,
                "carbohydrate": 6.68,
                "protein": 0.48,
                "fat": 0.04,
                "saturated_fat": null,
                "polyunsaturated_fat": null,
                "monounsaturated_fat": null,
                "trans_fat": null,
                "cholesterol": 0,
                "sodium": 9,
                "potassium": 43,
                "fiber": null,
                "sugar": null
            ,
            
                "id": "53d151c138313800099c0100",
                "consumed_on": "2014-07-24",
                "food_id": 38720,
                "serving_id": 48329,
                "quantity": 0.5,
                "name": "Australian Lamb Leg (Sirloin Chops, Boneless, Trimmed to 1/8\" Fat)",
                "brand": null,
                "description": "1 lb",
                "meal_type": "breakfast",
                "calories": 471.5,
                "carbohydrate": 0,
                "protein": 41.57,
                "fat": 32.615,
                "saturated_fat": 15.6445,
                "polyunsaturated_fat": 1.472,
                "monounsaturated_fat": 13.3315,
                "trans_fat": null,
                "cholesterol": 149.5,
                "sodium": 134,
                "potassium": 698.5,
                "fiber": null,
                "sugar": null
            ]
      
 

我使用的获取请求块如下:

 [[RKObjectManager sharedManager] addFetchRequestBlock:^NSFetchRequest *(NSURL *URL) 
    RKPathMatcher *pathMatcher = [RKPathMatcher pathMatcherWithPattern:@"nutrition/days/:date"];
    NSDictionary *argsDict = nil;
    BOOL match = [pathMatcher matchesPath:[URL relativePath] tokenizeQueryStrings:NO parsedArguments:&argsDict];
    NSDate *date;
    if (match) 
        date = [[[RDFormatters sharedManager] dashFormatUTC] dateFromString:[argsDict objectForKey:@"date"]];
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"FoodEntry"];
        fetchRequest.predicate = [NSPredicate predicateWithFormat:@"day.date = %@", date];
        return fetchRequest;
    
    return nil;
];

此 FetchRequest 返回与当天调用相关的所有 FoodEntries,但是,我认为我没有正确执行调用。我意识到这一点是因为

    它崩溃了(呃!) API 调用的响应通常是 Day 对象,但在执行 FetchRequest 后,它变成了 FoodEntry 对象 - 与我试图删除的 FoodEntry 对象完全相同。

有没有办法通过 Restkit 删除关系中的孤立对象?什么是正确的方法?

=================================

这是崩溃日志

2014-07-25 08:38:18.158 Euco[6918:60b] I restkit.network:RKObjectRequestOperation.m:180 GET 'https://example.com/api/v1/nutrition/days/2014-07-24'
2014-07-25 08:38:18.831 Euco[6918:f03] I restkit.network:RKObjectRequestOperation.m:250 GET 'https://example.com/api/v1/nutrition/days/2014-07-24' (200 OK / 4 objects) [request=0.6671s mapping=0.0053s total=0.6881s]
2014-07-25 08:38:18.831 Euco[6918:60b] -[FoodEntry nutrition_plan]: unrecognized selector sent to instance 0x10ab5ff20
(lldb) po self.day
<FoodEntry: 0x10ab5ff20> (entity: FoodEntry; id: 0xd000000000040012 <x-coredata://1CAD1FBC-F8EE-4A9C-A1B4-7DCDF2A5F1D7/FoodEntry/p1> ; data: <fault>)
2014-07-25 08:38:58.103 Euco[6918:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[FoodEntry nutrition_plan]: unrecognized selector sent to instance 0x10ab5ff20'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001038a1495 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001032c299e objc_exception_throw + 43
    2   CoreFoundation                      0x000000010393265d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation                      0x0000000103892d8d ___forwarding___ + 973
    4   CoreFoundation                      0x0000000103892938 _CF_forwarding_prep_0 + 120
    5   Euco                                0x0000000100036ff8 -[JournalNutritionViewController numberOfSectionsInTableView:] + 88
    6   UIKit                               0x00000001024ec8e2 -[UITableViewRowData(UITableViewRowDataPrivate) _updateNumSections] + 86
    7   UIKit                               0x00000001024ed5b5 -[UITableViewRowData invalidateAllSections] + 66
    8   UIKit                               0x000000010238b0cc -[UITableView _updateRowData] + 191
    9   UIKit                               0x000000010239c225 -[UITableView noteNumberOfRowsChanged] + 91
    10  UIKit                               0x000000010239bd27 -[UITableView reloadData] + 717
    11  Euco                                0x00000001000368c8 __42-[JournalNutritionViewController setDate:]_block_invoke + 184
    12  Euco                                0x0000000100067f7e __57+[Day(ModelFunctions) read:withType:withSuccess:failure:]_block_invoke + 142
    13  Euco                                0x0000000100200b3b __66-[RKObjectRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke242 + 91
    14  libdispatch.dylib                   0x0000000103e50851 _dispatch_call_block_and_release + 12
    15  libdispatch.dylib                   0x0000000103e6372d _dispatch_client_callout + 8
    16  libdispatch.dylib                   0x0000000103e533fc _dispatch_main_queue_callback_4CF + 354
    17  CoreFoundation                      0x00000001038ff289 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
    18  CoreFoundation                      0x000000010384c854 __CFRunLoopRun + 1764
    19  CoreFoundation                      0x000000010384bd83 CFRunLoopRunSpecific + 467
    20  GraphicsServices                    0x0000000104af0f04 GSEventRunModal + 161
    21  UIKit                               0x00000001022d7e33 UIApplicationMain + 1010
    22  Euco                                0x0000000100063113 main + 115
    23  libdyld.dylib                       0x00000001040b45fd start + 1
    24  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

当我添加异常断点时,它会在崩溃前停止:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return self.day.nutrition_plan.meal_goals.count

当它在那里中断时,如果我在控制台中运行po self.day,它会返回&lt;FoodEntry: 0x10ab5ff20&gt;,所以它以某种方式认为Day 对象是FoodEntry 对象。

【问题讨论】:

显示崩溃详细信息(消息和堆栈跟踪)以及您用于测试的代码it becomes a FoodEntry object 嘿@Wain 感谢您与我们联系!我刚刚用跟踪更新了我的问题(在底部)。 似乎与 fetch 块无关。你在哪里设置self.day @Wain 收到回复后,我设置了self.day。我认为问题在于 FetchRequest 块正在对 FoodEntry 实体执行 FetchRequests,而 API 调用是对 Day 实体进行的(即使它们是通过关系连接的)。 [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) self.day = (Day *)mappingResult.firstObject; failure:^(RKObjectRequestOperation *operation, NSError *error) failure([operation decodeErrors]); ]; 我一直在阅读这个github.com/RestKit/RestKit/issues/1737 和这个restkit.org/api/development/Classes/… 并且似乎无法掌握如何通过内置的Restkit 方法执行这种类型的孤立对象清理。是否有可能我需要推出自己的解决方案或者我忽略了什么? 【参考方案1】:

根据您的描述,您的孤块看起来不错。它会验证正在处理的 URL,因此应在适当的时间进行拍卖。

这段代码:

self.day = (Day *)mappingResult.firstObject;

在许多情况下是一种风险,因为您不能始终确定映射结果中的第一个对象是什么。如果:

    您有多个映射对象(嵌套) 您有多个响应描述符(导致 1.)

那么映射结果应该作为字典进行查询,并且您应该在将它们转换为您希望的内容之前检查内容。基本上从不将映射结果作为数组访问。

【讨论】:

以上是关于从关系中删除孤立对象的主要内容,如果未能解决你的问题,请参考以下文章

sql Wordpress - SQL查询删除孤立的Postmeta和分类关系

sql Wordpress - SQL查询删除孤立的Postmeta和分类关系

sql Wordpress - SQL查询删除孤立的Postmeta和分类关系

sql Wordpress - SQL查询删除孤立的Postmeta和分类关系

从表中删除孤立记录[关闭]

查找三个表中的孤立行