问题
This project uses Mogenerator and Magical Record. I have tracked down a bug to the fact that awakeFromInsert
is getting called twice. Once for each of my contexts I presume. This is an issue because I need to listen for NSNotifications on this NSManagedObject like this:
- (void)awakeFromInsert
{
// Listen for a return from background mode
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enteringForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
But awakeFromInsert get's called twice which is rather annoying. I want to call a method ONCE when my NSManagedObject is first created.
After searching this solution seems to make a lot of sense. However I can't see how I can add a category onto NSManagedObject when using Mogenerator and MagicalRecord. Without some complex overriding.
In MagicalRecord MR_createEntity
calls
if ([self respondsToSelector:@selector(insertInManagedObjectContext:)])
{
id entity = [self performSelector:@selector(insertInManagedObjectContext:) withObject:context];
return entity;
}
Is there a neater solution to this issue?
回答1:
Ok well this feels very hacky but appears to work. I created the following class methods on my human readable NSManagedObject class:
+ (id)insertInManagedObjectContext:(NSManagedObjectContext*)moc_ {
JWBoard *newobject = [super insertInManagedObjectContext:moc_];
[JWBoard awakeFromCreate:newobject];
return newobject;
}
+ (void)awakeFromCreate:(JWBoard *)board
{
// do setup stuff & add observers
}
Open to much better solutions!
回答2:
Open to much better solutions!
I wish! Would have been easy enough for apple to not invoke awakeFromInsert, or to at least provide a flag that's true in the context of a "parentProcessSaveRequest." If you look at the call stack for the not-first calls to awakeFromInsert
, the stack always contains parentProcessSaveRequest
.
Here's some terrible code proving as much:
- (void) awakeFromInsert
{
[super awakeFromInsert];
NSArray* stackArray = [NSThread callStackSymbols];
for (NSString* method in stackArray)
{
if ([method rangeOfString:@"_parentProcessSaveRequest"].location != NSNotFound)
{
NSLog(@"Parent insert %@",self.objectID);
return;
}
}
NSLog(@"First insert %@",self.objectID);
// Initialize here
}
And the log output -- the objectId stays the same:
2014-05-19 20:53:52.964 myApp[1891:a01f] First insert 0x6000000326c0 <x-coredata:///MyEntity/t496E9B17-E170-4A7C-B7D4-7D8B92433E1C2>
2014-05-19 20:53:53.531 myApp[1891:303] Parent insert 0xdca8000eb <x-coredata://7274869F-4BF3-4B8A-9270-A64E54476AAD/MyEntity/p14122>
2014-05-19 20:53:53.537 myApp[1891:303] Parent insert 0xdca8000eb <x-coredata://7274869F-4BF3-4B8A-9270-A64E54476AAD/MyEntity/p14122>
Seems to work for saving to any of the nested contexts that I have, ugly as it is.
Unfortunately I cant figure any reasonable way to determine whether awakeFromInsert is being called in the context of a parentProcessSaveRequest. Come on, Apple! Give us a flag here.
回答3:
here is the simplest one: when parentContext is null, means when this context is saved you can do you custom logic, for example incrementing table number
- (void)awakeFromInsert
{
if (!self.managedObjectContext.parentContext) {
//setting tableNumber
[self willChangeValueForKey:@"number"];
[self setPrimitiveNumber:tableNumber];
[self didChangeValueForKey:@"number"];
}
}
来源:https://stackoverflow.com/questions/19893775/awakefrominsert-called-twice-with-nested-contexts