从关系中删除孤立对象
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
,它会返回<FoodEntry: 0x10ab5ff20>
,所以它以某种方式认为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和分类关系