With further to my question and it's solution mentioned here: https://stackoverflow.com/a/19153387/260665 the only way to solve the problem was to implement @try-@catch
block and gracefully handle the exceptions by clearing off the results of the threads in case of exceptions.
This is my try-catch block:
// These operations are meant to calculate statistics for the Task objects, now when the statistics are being calculated there are possibilities that the main thread might delete the ManagedObject from it's MOC and write to the store. Now this means that ManagedObjects here may not have an equivalent record back in the store to refer!
// So, when the already faulted objects try to access it's properties, NSObjectInaccessibleException arises. For more details check the SO post: https://stackoverflow.com/questions/18828164/coredata-object-fault-in-independent-managedobjectcontext-vs-changes-in-persiste
// Hence catching the exception and returning back no results is the best approach as of now!
@try
{
CSStatistics *theStats = [self statisticsOperationFromDate:self.dateRange.fromDate
toDate:self.dateRange.toDate];
[self setOutStatistics:theStats];
if ([(NSObject*)[self resultDelegate] respondsToSelector:@selector(statisticsOperationCompletedWithOperation:)])
{
[(NSObject*)[self resultDelegate] performSelectorOnMainThread:@selector(statisticsOperationCompletedWithOperation:)
withObject:self
waitUntilDone:NO];
}
}
@catch (NSException *exception)
{
DEBUGLog(@"Most probably a NSObjectInaccessibleException exception! - %@", exception);
[self setOutStatistics:nil]; // We would not like to give out erroneous reports! Mind it!
}
@finally
{
}
Strange things happen, my try-catch block works perfectly well in distribution build where as the app crashes in debug and release builds. Apparently, the exception when raised is handled somewhere and it is not passed to the @catch
block but it is consumed instead. I cannot figure out where as Xcode gives no further details of the same.
This is the log in debug mode:
2013-10-23 14:33:07.293 CATSXT[64267:650b] *** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x1912fc00 <x-coredata://6E14A109-8A14-4369-BBC5-468D790A8D9E/CSTask/p7562>''
*** First throw call stack:
(0x33af012 0x2d25e7e 0x2a4ba48 0x2a4b3f7 0x2a4b031 0x2a4aea6 0x10eb42e2 0x5e02d 0x242e00b 0x2a86fc4 0x5cc58 0x244c247 0x5d492 0x244c205 0x5d492 0x246d23c 0x2440c70 0x15c075 0x15caac 0x15c6dd 0x244e453 0x244e164 0x24daa31 0x601253f 0x6024014 0x60152e8 0x6015450 0x949b0e72 0x94998d2a)
libc++abi.dylib: terminate called throwing an exception
Some googling showed me that the 'All Exceptions' breakpoint results in such behavior but I have disabled that breakpoint as well. Now I still cannot figure out why @catch
block is not executed in debug and release builds but it works perfectly well in distribution builds. This does not trouble the users of production app but it definitely hurts the development process.
Any leads would be much appreciated.