RESTKit:错误没有解雇

时间:2014-07-26 08:20:31

标签: core-data restkit restkit-0.20 fault

我无法在Core Data中触发错误

的.m

@property (strong, nonatomic) RKObjectManager *objectManager;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

...

- (RKObjectManager *)setupObjectManager
{

    NSURL *baseURL = [NSURL URLWithString:kRESTBaseUrl];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc]initWithBaseURL:baseURL];
    RKObjectManager *manager = [[RKObjectManager alloc]initWithHTTPClient:httpClient];
    [manager.HTTPClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
    [manager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
    [manager.HTTPClient setParameterEncoding:AFJSONParameterEncoding];
    [RKMIMETypeSerialization registeredMIMETypes];
    [RKObjectManager setSharedManager:manager];

    return [RKObjectManager sharedManager];

}

- (RKObjectManager *)getObjectManager
{
    self.objectManager = (!self.objectManager) ?  [self setupObjectManager] : self.objectManager;
    return self.objectManager;
}

- (void)getManagedObjectFromAppDelegate
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    self.objectManager = [self getObjectManager];

    self.objectManager.managedObjectStore = appDelegate.managedObjectStore;
    self.managedObjectContext = self.objectManager.managedObjectStore.mainQueueManagedObjectContext;

}

我在本地获取User,如果没有找到,我就会获取服务器。

找到User后,我在主队列上设置标签属性,这就是应用崩溃的地方,因为故障永远不会触发,所有内容都是nil

- (void)didFinishFindingUser:(NSString*)user withResults:(NSArray*)results
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (results.count > 0)
        {
            self.inviteUser = (User*)[results firstObject];
            [self setNameForUser:self.inviteUser];
        }
    });
}

- (void)setNameForUser:(User*)user
{
    [self.activityIndicator stopAnimating];
    NSLog(@"User.firstName %@", user.firstName);
    //Code here to configure the labels
    //This is where the App crashes as the values are coming as nil
}

记录:

2014-07-26 00:46:16.324 App[12455:60b] User.firstName (null)
(lldb) po user.managedObjectContext
 nil
(lldb) po user
<User: 0x1780ac5a0> (entity: User; id: 0xd000000000040008 <x-coredata://99A54059-0A51-402C-9633-B47843B6414B/User/p1> ; data: <fault>)

(lldb) 

正如您所看到的那样,我正在通过NSLog访问一个属性来触发故障,但它没有触发。

[User managedObjectContext] == nil

如何解决故障并获取属性?

**更新**

我已经将问题缩小到当我调用main_queue时,对象在没有上下文的情况下转入故障。

CODE

- (void)didFinishFindingUser:(NSString*)user withResults:(NSArray*)results
{
        if (results.count > 0)
        {
            self.inviteUser = (User*)[results firstObject];
            NSLog(@"***** Thread BEFORE main_queue: %@", [NSThread currentThread]);
            NSLog(@"NewUser %@", self.inviteUser);
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"***** Thread AFTER main_queue: %@", [NSThread currentThread]);
                NSLog(@"NewUser %@", self.inviteUser);
            [self setNameForUser:self.inviteUser];
            });

        }
}

- (void)setNameForUser:(User*)user
{

    NSString *firstInitial = user.firstName.length > 0 ? [user.firstName substringToIndex:kInitialIndex] : [kFirstNamePlaceholder substringToIndex:kInitialIndex];
    NSString *lastInitial = user.lastName.length > 0 ? [user.lastName substringToIndex:kInitialIndex] : [kLastNmaePlaceholder substringToIndex:kInitialIndex];

    self.labelInitials.text = [firstInitial stringByAppendingString:lastInitial];
    self.labelName.text = [NSString stringWithFormat:@"%@ %@", user.firstName.length > 0 ? user.firstName : kFirstNamePlaceholder, user.lastName.length > 0 ? user.lastName : kLastNmaePlaceholder];
    self.labelUserID.text = [@"@" stringByAppendingString:user.userid];
}

LOG:

2014-07-27 06:01:03.197 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4}
2014-07-27 06:01:03.198 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380>
2014-07-27 06:01:03.198 App[24030:3d07] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: {
    firstName = Lois;
    lastName = Lane;
    userid = "lois.lane";
})
2014-07-27 06:01:03.199 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4}
2014-07-27 06:01:03.199 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380>
2014-07-27 06:01:03.200 App[24030:3d07] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: {
    firstName = Lois;
    lastName = Lane;
    userid = "lois.lane";
})
2014-07-27 06:01:03.201 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4}
2014-07-27 06:01:03.201 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380>
2014-07-27 06:01:03.201 App[24030:3d07] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: {
    firstName = Lois;
    lastName = Lane;
    userid = "lois.lane";
})
2014-07-27 06:01:03.203 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4}
2014-07-27 06:01:03.203 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380>
2014-07-27 06:01:03.203 App[24030:3d07] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: {
    firstName = Lois;
    lastName = Lane;
    userid = "lois.lane";
})
2014-07-27 06:01:03.205 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4}
2014-07-27 06:01:03.205 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380>
2014-07-27 06:01:03.206 App[24030:3d07] NewUser <User: 0xd97fc00> (entity: User; id: 0xd97a510 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p2> ; data: {
    firstName = Lois;
    lastName = Lane;
    userid = "lois.lane";
})

2014-07-27 06:01:03.207 App[24030:60b] ***** Thread AFTER main_queue: <NSThread: 0xdf80f80>{name = (null), num = 1}
2014-07-27 06:01:03.207 App[24030:60b] User Context (null)
2014-07-27 06:01:03.207 App[24030:3d07] ***** Thread BEFORE main_queue: <NSThread: 0xd6b2750>{name = (null), num = 4}
2014-07-27 06:01:03.208 App[24030:60b] NewUser <User: 0xda83280> (entity: User; id: 0xda7c4f0 <x-coredata://5251395C-DDDC-424C-9372-EA8D883E0AE6/User/p1> ; data: <fault>)
2014-07-27 06:01:03.208 App[24030:3d07] User Context <NSManagedObjectContext: 0xdb9a380>
(lldb) 

当我尝试访问不存在的对象中的属性时,应用程序崩溃了。我认为问题出在了问题上?

更新2

- (void)didFinishFindingUser:(NSString*)user withResults:(NSArray*)results
{
    NSManagedObjectID *recordObjectID;
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    if (results.count > 0)
    {
        self.inviteUser = (User*)[results firstObject];
        recordObjectID = self.inviteUser.objectID;

        dispatch_async(dispatch_get_main_queue(), ^{
            NSManagedObjectContext *bgndContext = [[NSManagedObjectContext alloc] init];
            bgndContext = self.objectManager.managedObjectStore.mainQueueManagedObjectContext;
            bgndContext.persistentStoreCoordinator = appDelegate.managedObjectStore.persistentStoreCoordinator;
            NSError * error = nil;
            self.inviteUser = (User *) [bgndContext existingObjectWithID:recordObjectID error:&error];
            NSLog(@"***** Thread AFTER main_queue: %@", [NSThread currentThread]);
            NSLog(@"inviteUser Context %@", [self.inviteUser managedObjectContext]);
            NSLog(@"inviteUser %@", self.inviteUser);
            [self setNameForUser:self.inviteUser];
        });
    }
}

LOG:

2014-07-27 06:53:28.390 App[27898:60b] inviteUser Context (null)
2014-07-27 06:53:28.390 App[27898:60b] inviteUser (null)

2 个答案:

答案 0 :(得分:1)

尝试以下方法在主线程上下文中获取相应的对象:

recordObjectID = self.inviteUser.objectID;

    dispatch_async(dispatch_get_main_queue(), ^{
        NSManagedObjectContext *moc = self.objectManager.managedObjectStore.mainQueueManagedObjectContext;;
        NSError * error = nil;

        self.inviteUser = (User *) [moc existingObjectWithID:recordObjectID error:&error];

        NSLog(@"***** Thread AFTER main_queue: %@", [NSThread currentThread]);
        NSLog(@"inviteUser Context %@", [self.inviteUser managedObjectContext]);
        NSLog(@"inviteUser %@", self.inviteUser);
        [self setNameForUser:self.inviteUser];
    });

但请注意,在后台线程和后台管理对象上设置self.inviteUser是一个坏主意。您应该只从后台线程返回托管对象ID。

此外,如果您有一个对象管理器,那么您应该尝试使用一种方法在后台获取您的数据并切换到主线程(即如果您可以帮助它,则不直接使用操作)。

答案 1 :(得分:0)

您对象的托管对象上下文为nil,这就是无法触发故障的原因。获取用户对象时,请确保检查所有属性和上下文。

RestKit在多线程方面有很多这样的问题。鉴于您的大量代码只是为了设置&#34;对象管理器&#34;,您是否考虑过使用普通核心数据和NSURLSession