12 Nov 2013, 05:58
Generic-user-small

Chaitanya Gupta (2 posts)

In chapter 5 (Threading), page 78, is this paragraph:

Prior to iOS 6.0 and OS X 10.8 Mountain Lion, you could get away with using Core Data incorrectly in a multithreaded environment. If you read from NSManagedObject instances only on threads other than the one that created the instance and didn’t write to them, then things would work—usually. However, as of iOS 6.0 and OS X 10.8 Mountain Lion, that has changed. Core Data now monitors what thread the objects are being accessed from and will throw an exception if an improper access is detected. While this change can catch developers off-guard, it is a net win. We now have well-defined boundaries for what is correct and what is not.

I wanted to test this so I wrote a small method which is called from the main thread:

- (void)testMOCConfinement {
  NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
  context.persistentStoreCoordinator = [NSPersistentStoreCoordinator persistentStoreCoordinatorWithStoreFileName:@"MOCConfinementTest.sqlite"];
  dispatch_queue_t queue = dispatch_queue_create("A Serial Queue", DISPATCH_QUEUE_SERIAL);
  dispatch_async(queue, ^{
    TDTDisconnectedEntity *entity = [NSEntityDescription insertNewObjectForEntityForName:@"TDTDisconnectedEntity"
                                                                  inManagedObjectContext:context];
    entity.name = @"foobar";
    NSError *error;
    if (![context save:&error]) {
      NSLog(@"Couldn't save because: %@", error);
      abort();
    }
  });
}

Note that this relies on a few category methods and classes not defined here, but you get the gist of this. A context is created with the NSPrivateQueueConcurrencyType, so any of its operations must be done in a -performBlock:. However I create a managed object on a serial dispatch queue and even do a save on this dispatch queue, which should not be allowed. But I don’t get any exception when I run this – neither in the simulator not on an actual device. I am testing this on iOS 7.

This seems to go against what the above para in the book says. Am I doing something wrong with my test?

06 Dec 2013, 20:15
Avatarsmall_pragsmall

Marcus S. Zarra (253 posts)

They turned off the crash in recent releases because too many apps and people were crashing :/

There are some debug logs you can turn on to get the same effective behavior as before but the crashes are gone currently.

I am hoping they turn them back on at some point.

14 Jan 2014, 05:06
Generic-user-small

Chaitanya Gupta (2 posts)

Hi Marcus,

Can you tell me what exactly can I do to turn on these debug logs?

Thanks, Chaitanya

01 Jul 2014, 20:25
Avatarsmall_pragsmall

Marcus S. Zarra (253 posts)

It was that you had to download a debug version of the Core Data library and then run your application with the debug flag on. This only worked on OS X and the simulator. You could not run on the device in this mode.

Now as of iOS 8, you just turn on the debug flag and Core Data will load the right library and give you the detail you need.

  You must be logged in to comment