我无法在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)
答案 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
?