How does the userInfo NSManagedObjectContext property work?

In the current headers, it is declared as:

@property (nonatomic, readonly, strong) NSMutableDictionary *userInfo NS_AVAILABLE(10_7,  5_0);

      

The documentation just says:

Returns information about recipients.

  • What is the purpose of the context userInfo

    ? Other Core Data objects have vocabularies userInfo

    that can be set in the managed object model. It doesn't seem to be the case. Does this just mean a temporary cache that's more convenient than using linked objects?

  • Is it persistent or across NSCoding

    ?

  • Does it use the same flow model as context-managed objects?

+3


source to share


2 answers


What is the purpose of custom context information?

I looked at this in several ways and unfortunately didn't find anything definite.

  • Set a symbolic breakpoint on -[NSManagedObjectContext userInfo]

    and run a suite of Core Data regression tests that use most of the public API.
  • Looked at the Core Data binary structure using several reverse engineering tools.

Using a symbolic breakpoint didn't do much, although it's possible that the version of Xcode I was using just swept past it. Nothing seems to be accessing a public accessory, but given the internal Core Data, which is not surprising.

Disassembling this method gave several hints:

void * -[NSManagedObjectContext userInfo](void * self, void * sel) {
    rsi = sel;
    rbx = self;
    if (*(int32_t *)__PF_Threading_Debugging_level != 0x0) {
            __PFAssertSafeMultiThreadedAccess_impl(rbx, rsi);
    }
    rax = *_OBJC_IVAR_$_NSManagedObjectContext._additionalPrivateIvars;
    rax = *(rbx + rax);
    rax = *(rax + 0x30);
    return rax;
}

      

The method checks if concurrency debugging is actually active and this method is used correctly in concurrency rules (this answers question 3). This method directly accesses a private instance variable _additionalPrivateIvars

from which other pieces of Core Data are read and written. Several of the change tracking / programming and optimism optimization techniques use this instance variable. -lockObjectStore

, for example, is written _additionalPrivateIvars

to NSManagedObjectContext

.



A bit strange that it NSMutableDictionary

is read-only. You can't install a new one NSMutableDictionary

, but you can happily set keys and values โ€‹โ€‹on it. I was able to do this quite easily:

(lldb) po [[[result managedObjectContext] userInfo] setValue:@"foo" forKey:@"bar"]
0x0000000000000020

(lldb) po [[result managedObjectContext] userInfo]
{
    bar = foo;
}

      

Without more detailed guidance from Apple, I wouldn't want to do this in production code, as it can be dangerous to write in this.

Is it persistent or NSCoding?

It doesn't look like it and it doesn't make a lot of sense. Persistent stores are unaware of the contexts that access them through the coordinator, and if the vocabulary userInfo

was important to the store, it should be covered in the Atomic Store Programming Guide and the Incremental Store Programming Guide.

Does it use the same flow model as context-managed objects?

This is definite, and if concurrency debugging is active, misuse -userInfo

will log the assertion.

+2


source


The documentation for this particular API is remarkably sparse (general text:) The receiverโ€™s user info.

. However, the vocabulary userInfo

is very standard within apples. It is available to the user to add custom information without having to subclass (see the documentation on NSNotification

s for example userInfo

).

The fact that NSManagedObjectContext

s userInfo

is read-only is not a problem. Instead of assigning a property to a dictionary, as you might expect:

// useful while debugging multiple Core Data threads
*moc.userInfo = @{@"name":@"main managed object context"};

      



just accessing the dictionary directly (it's changed after all):

*moc.userInfo[@"name"] = @"main managed object context"

      

0


source







All Articles