从关系中删除孤立对象

时间:2014-07-24 20:55:12

标签: ios restkit restkit-0.20

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

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

/nutrition/days/2014-07-14

的API调用
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,但是,我认为我没有正确执行通话。我意识到这一点,因为

  1. 它崩溃了(呃!)
  2. API调用的响应通常是Day个对象,但在执行FetchRequest之后,它变为FoodEntry个对象 - 我尝试的FoodEntry个对象。删除。
  3. 有没有办法通过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对象。

1 个答案:

答案 0 :(得分:0)

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

此代码:

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

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

  1. 您有多个映射对象(嵌套)
  2. 您有多个响应描述符(导致1。)
  3. 然后应该将映射结果作为字典查询,您应该在将它们转换为您希望的内容之前检查内容。基本上从不以数组形式访问映射结果。