Managed Objects have different id when fetched

雨燕双飞 提交于 2020-01-04 13:47:42

问题


im working with coredata and there is a concept that im not getting; i've 2 managed objects ACConversation and ACMessages with a one to many relationship, so i'm saving a message associated to a conversation and trying to fetch them back based on:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.conversation = %@", self.conversation];

but the id associated to the object is different (it seems more a memory address) and with the above predicate it doesnt fetch anything:

2013-01-01 18:32:13.727 CoreDataTest[9325:c07] The message to fetch: <NSManagedObject: 0x818f680> (entity: ACMessage; id: 0x8160630 <x-coredata:///ACMessage/t451CC5A3-5972-479C-BC7C-6B91CA4DA23C4> ; data: {
    conversation = "0x818b770 <x-coredata:///ACConversation/t451CC5A3-5972-479C-BC7C-6B91CA4DA23C2>";
    sentDate = "2013-01-01 23:32:13 +0000";
    text = "Test message to Fetch through relationship!!!";
})
2013-01-01 18:32:13.728 CoreDataTest[9325:c07] The conversation associated to the message: <NSManagedObject: 0x818b710> (entity: ACConversation; id: 0x818b770 <x-coredata:///ACConversation/t451CC5A3-5972-479C-BC7C-6B91CA4DA23C2> ; data: {
    draft = nil;
    lastMessageSentDate = "2013-01-01 23:32:13 +0000";
    lastMessageText = "Test message to Fetch through relationship!!!";
    messages =     (
        "0x8160630 <x-coredata:///ACMessage/t451CC5A3-5972-479C-BC7C-6B91CA4DA23C4>"
    );
    messagesLength = 0;
    unreadMessagesCount = 0;
    users =     (
        "0x818b610 <x-coredata:///ACUser/t451CC5A3-5972-479C-BC7C-6B91CA4DA23C3>"
    );
})

2013-01-01 18:32:13.782 CoreDataTest[9325:c07] The conversation found is: <NSManagedObject: 0x835e440> (entity: ACConversation; id: 0x8199860 <x-coredata://6E4B40F2-F7B4-4275-BF6E-349101A1254F/ACConversation/p290> ; data: <fault>)
2013-01-01 18:32:13.783 CoreDataTest[9325:c07] The conversation to find is: <NSManagedObject: 0x818b710> (entity: ACConversation; id: 0x835e2e0 <x-coredata://6E4B40F2-F7B4-4275-BF6E-349101A1254F/ACConversation/p296> ; data: {
    draft = nil;
    lastMessageSentDate = "2013-01-01 23:32:13 +0000";
    lastMessageText = "Test message to Fetch through relationship!!!";
    messages =     (
        "0x835e6d0 <x-coredata://6E4B40F2-F7B4-4275-BF6E-349101A1254F/ACMessage/p268>"
    );
    messagesLength = 0;
    unreadMessagesCount = 0;
    users =     (
        "0x835ea20 <x-coredata://6E4B40F2-F7B4-4275-BF6E-349101A1254F/ACUser/p296>"
    );
})

below the code:

- (NSFetchedResultsController *)fetchedResultsController {

    if (_fetchedResultsController) {
        NSLog(@"_fetchedResultsController found: %@", _fetchedResultsController);
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"ACMessage"];
    NSError __autoreleasing *error = nil;
    NSUInteger messagesCount = [managedObjectContext countForFetchRequest:fetchRequest error:&error];
    NSAssert(messagesCount != NSNotFound, @"-[NSManagedObjectContext countForFetchRequest:error:] error:\n\n%@", error);
    if (messagesCount > MESSAGE_COUNT_LIMIT) {
        [fetchRequest setFetchOffset:messagesCount-MESSAGE_COUNT_LIMIT];
    }
    [fetchRequest setFetchBatchSize:10];
    [fetchRequest setSortDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"sentDate" ascending:YES]]];

    /*
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.conversation = %@", self.conversation];
    [fetchRequest setPredicate:predicate];
    //NSLog(@"Predicate: %@", predicate);
    */

    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"ACMessage"];

    _fetchedResultsController.delegate = self;

    NSAssert([_fetchedResultsController performFetch:&error], @"-[NSFetchedResultsController performFetch:] error:\n\n%@", error);
    return _fetchedResultsController;
}

- (void) setSimpleData
{
    self.conversation = [NSEntityDescription insertNewObjectForEntityForName:@"ACConversation" inManagedObjectContext:managedObjectContext];
    self.conversation.lastMessageSentDate = [NSDate date];
    ACUser *user = [NSEntityDescription insertNewObjectForEntityForName:@"ACUser" inManagedObjectContext:managedObjectContext];
    [user setName: @"my user"];
    [user setElementId: @"kjh123k123"];

    [self.conversation addUsersObject:user];

    ACMessage *message = [NSEntityDescription insertNewObjectForEntityForName:@"ACMessage" inManagedObjectContext:managedObjectContext];
    self.conversation.lastMessageSentDate = message.sentDate = [NSDate date];
    self.conversation.lastMessageText = message.text = @"Test message to Fetch through relationship!!!";
    [self.conversation addMessagesObject:message];

    NSLog(@"The message to fetch: %@", message);
    //NSLog(@"The user associated to the conversation: %@", user);
    NSLog(@"The conversation associated to the message: %@", self.conversation);

    NSError *error;
    if (![[self managedObjectContext] save:&error]) {
        //Make sure you handle this!
        NSLog(@"ERROR: Can't save object context");
        exit(-1);
    }
}

- (void) getSimpleData
{
    NSError *error;

    if (![[self fetchedResultsController] performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }

    NSInteger section = 0;
    id  sectionInfo = [[[self fetchedResultsController] sections] objectAtIndex:section];

    if ([sectionInfo numberOfObjects]>0) {

        NSIndexPath *my0 = [NSIndexPath indexPathForRow:0 inSection:0];
        ACMessage *message = [self.fetchedResultsController objectAtIndexPath:my0];

        ACConversation *conv = message.conversation;

        NSLog(@"The message fetch at index 0 is %@", message);
        NSLog(@"The conversation found is: %@", conv);
        NSLog(@"The conversation to find is: %@", self.conversation);

    } else {
        NSLog(@"No messages found!");
    }
}

am i missing something or i have to set an id in ACConversation and use it in the NSPredicate to find all the messages associated to the conversation?

thanks! alex


回答1:


When you first create a managed object it has a temporary objectID. That gets changed to a permanent objectID when you save changes. This is the only time it changes-- from the original temporary value to a later permanent value. The differences you're seeing are exactly what's expected when this change happens.

You can check whether an object has a temporary ID like this:

BOOL hasTempID = [[myManagedObject objectID] isTemporaryID];

You can also force the conversion to happen early-- before you've saved changes-- like this:

NSError *error = nil;
BOOL success = [managedObjectContext obtainPermanentIDsForObjects:@[myManagedObject] error:&error];


来源:https://stackoverflow.com/questions/14115646/managed-objects-have-different-id-when-fetched

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!