Core Data background thread NSManagedObjectContext merging error - iphone

I'm writing an Ipad app that shows articles and downloads new articles in a separate NSOperation on a queue and inserts them into core data. Currently I have a separate context for the operation, created in the main method of the operation and using the same coordinator as the main context. I use the same pattern that has been suggested alot of listening in that operation for NSManagedObjectContextDidSaveNotification and then calling mergeChangesFromContextDidSaveNotification on the main thread context. The problem is I'm getting this error:
2011-01-27 07:26:02.574 Zagazine[12298:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator'
*** Call stack at first throw:
(
0 CoreFoundation 0x3284b987 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x31aca49d objc_exception_throw + 24
2 CoreData 0x3549d07b _PFRetainedObjectIDCore + 638
3 CoreData 0x3549cdfb - [NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:] + 14
4 CoreData 0x354bf85b -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 2170
5 CoreFoundation 0x327e9bbf -[NSObject(NSObject) performSelector:withObject:] + 22
6 Foundation 0x320fd795 __NSThreadPerformPerform + 268
7 CoreFoundation 0x328017dd __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
8 CoreFoundation 0x327d34fb __CFRunLoopDoSources0 + 194
9 CoreFoundation 0x327d2e5b __CFRunLoopRun + 230
10 CoreFoundation 0x327d2c87 CFRunLoopRunSpecific + 230
11 CoreFoundation 0x327d2b8f CFRunLoopRunInMode + 58
12 GraphicsServices 0x3094a4ab GSEventRunModal + 114
13 GraphicsServices 0x3094a557 GSEventRun + 62
14 UIKit 0x32c14329 -[UIApplication _run] + 412
15 UIKit 0x32c11e93 UIApplicationMain + 670
16 ArticleApp 0x0000233f main + 70
17 ArticleApp 0x000022f4 start + 40
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
This interesting part is that this error only occurs the first time I launch the app after installing it. All subsequent launches after it's installed work fine. Does anyone know why this error is happening and why it would only happen on initial install.
Also, this is how I'm merging the context, this is called on background thread when it receives notification:
- (void)mergeChanges:(NSNotification *)notification {
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *mainContext = [appDelegate managedObjectContext];
// Merge changes into the main context on the main thread
[mainContext performSelectorOnMainThread:#selector(mergeChangesFromContextDidSaveNotification:)
withObject:notification
waitUntilDone:YES];
}

This interesting part is that this error only occurs the first time I launch the app after installing it. All subsequent launches after it's installed work fine. Does anyone know why this error is happening and why it would only happen on initial install.
My guess then is that the persistent store is not correctly associated to the file on the disk correctly at the first launch. The file backing the Core Data store does not materialize when you assign its URL to the persistent store coordinator. It only materializes when it is first saved.
And merging changes without having a backed file ready causes a lot of problems.
Try saving the context once from the main thread at the first launch very early in the execution, when the Core Data context is still empty, before creating the background thread. Hopefully that will solve your issue.

Did you have any other mergeChangesFromContextDidSaveNotification notification being observed by any other context? If so, it might be the order you're notifying. It might be notifying to a context who doesn't know about the schema the changes are affecting to (aka, 'Object's persistent store is not reachable from this NSManagedObjectContext's coordinator').

Related

How to fix 'outlined consume of Model?' runtime crash on Swift 5

I just upgraded one of my apps to Swift 5, I didn't change so much at all and there didn't seem to be any problems, so I just released it in production (fortunately in phased release).
After 1 days I started to see a very strange crash on Crashlytics that affect the 15% of people that is using my app.
This is the stack trace:
Crashed: com.apple.main-thread
0 (Missing) 0x31698aa1503e0 (Missing)
1 libswiftCore.dylib 0x1afa5ac68 _swift_release_dealloc + 28
2 App 0x104194c3c outlined consume of MyModel? + 4300033084
3 App 0x104482cb8 #objc MyController.__ivar_destroyer (<compiler-generated>)
4 libobjc.A.dylib 0x180f267cc object_cxxDestructFromClass(objc_object*, objc_class*) + 148
5 libobjc.A.dylib 0x180f366b8 objc_destructInstance + 68
6 libobjc.A.dylib 0x180f36720 object_dispose + 16
7 UIKitCore 0x1ae2edac0 -[UIResponder dealloc] + 152
8 UIKitCore 0x1add173e0 -[UIViewController dealloc] + 1748
9 App 0x10431d82c BaseViewController.__deallocating_deinit (MyController.swift:56)
10 App 0x10431d85c #objc BaseViewController.__deallocating_deinit (<compiler-generated>)
11 libobjc.A.dylib 0x180f41b9c (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 672
12 CoreFoundation 0x181d59f40 _CFAutoreleasePoolPop + 28
13 CoreFoundation 0x181cd8e00 __CFRunLoopRun + 1932
14 CoreFoundation 0x181cd8354 CFRunLoopRunSpecific + 436
15 GraphicsServices 0x183ed879c GSEventRunModal + 104
16 UIKitCore 0x1ae2c3b68 UIApplicationMain + 212
17 App 0x104108468 main (AppDelegate.swift:21)
18 libdyld.dylib 0x18179e8e0 start + 4
I searched already something on the web but I find only a thread on the Swift Forum not very related to this.
MyModel is actually a struct model that is nested into another Model.
MyController is the very huge controller that manages the model.
The crash seems to happen obviously when popping the controller and so when the System tries to deallocate all the related properties.
I tried to replicate it many times with no results, and I didn't know really where to start looking.
Someone had the same problem?
UPDATE [Partially Fixed]:
It seemed to be a stack corruption caused by a Advertising Framework, to fix this I moved MyModel from Struct to Class, it's now on the Heap and can't get double freed.
From my experience, most of the outlined consume of errors are caused by concurrency issue. When one queue/thread reading the struct while another queue/thread modifying it without synchronization (mutex, semaphore, barrier, etc).
You need to check all threads stacks to see which thread access MyModel simultaneously with the Main(crashed) thread.

How to read Xcode console output?

As a Java and PHP developer new to Xcode, I am having trouble dealing with memory errors. I have a sample program from a book, which crashes on startup with "Program received signal 'SIGABRT'." I don't know what to do with the console output below. I realize it's some kind of stack trace, but the name on the left is just the name of the application, not a class or file. I don't know what "main + 121" or "start + 53" means or where to look. Any guidance would be appreciated.
2011-05-11 10:43:23.071 FlowerInfoNavigator[22537:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary objectForKey:]: method sent to an uninitialized mutable dictionary object'
*** Call stack at first throw:
(
0 CoreFoundation 0x00dc25a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f16313 objc_exception_throw + 44
2 CoreFoundation 0x00dbf542 -[__NSPlaceholderDictionary objectForKey:] + 194
3 FlowerInfoNavigator 0x0000289a -[RootViewController tableView:didSelectRowAtIndexPath:] + 330
4 UIKit 0x0008bb68 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
5 UIKit 0x00081b05 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 219
6 Foundation 0x0079b79e __NSFireDelayedPerform + 441
7 CoreFoundation 0x00da38c3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
8 CoreFoundation 0x00da4e74 __CFRunLoopDoTimer + 1220
9 CoreFoundation 0x00d012c9 __CFRunLoopRun + 1817
10 CoreFoundation 0x00d00840 CFRunLoopRunSpecific + 208
11 CoreFoundation 0x00d00761 CFRunLoopRunInMode + 97
12 GraphicsServices 0x00ffa1c4 GSEventRunModal + 217
13 GraphicsServices 0x00ffa289 GSEventRun + 115
14 UIKit 0x00022c93 UIApplicationMain + 1160
15 FlowerInfoNavigator 0x00001b99 main + 121
16 FlowerInfoNavigator 0x00001b15 start + 53
)
terminate called after throwing an instance of 'NSException'
(gdb)
On the right are the methods that were called that are on the stack. I generally just look for anything that is from one of my methods (though this won't always work) and then it'll give you the method call that the problem originated from. in the trace at call number 3 on "FlowerInfoNavigator" the method tableView:didSelectRowAtIndexPath: was called and somewhere in there is what caused the crash. You should be able to use the debugger and breakpoints to narrow it down from there hopefully. Good luck.
Edit: as I relooked at your error message: at the top of it it gives you the error. You tried to retrieve an object from a NSDictionary that wasn't initialized yet, and from above, it occurred in your didSelectRowAtIndexPath method
The console wouldn't be the only place you look. Take a look at your Debugger too. Over there there is usually one line that is bolded. If you tap that it'll show you exactly where the crash happened.
Looks like you didn't init your NSDictionary
The Crash is due to nsdictionary is not initialized yet and how to search for during a crash ,first look at console so you will get idea about what caused the crash or exception and to get where the application crashed you can check out debugger .In the debugger the the particlar line will be in bold where the application crashed.
Apart from you can also use NSZombieEnabled (BOOL) to get what is causing the application crash .More about NSZombieEnabled can be found here http://developer.apple.com/library/ios/#documentation/Xcode/Conceptual/iphone_development/130-Debugging_Applications/debugging_applications.html
Note : here do make sure to make NSZombieEnabled set to NO at time of processing the application to submission to apple store.
Hope this helps.

CoreData: Crash purging caches after a Memory warning

I've got a stack trace showing a crash responding to a memory warning:
Thu Oct 28 00:42:55 iPhone DTMobileIS[10853] : _memoryNotification : {name = (null), num = 1}
Thu Oct 28 00:42:55 iPhone DTMobileIS[10853] : _memoryNotification : {
OSMemoryNotificationLevel = 1;
timestamp = "2010-10-28 07:42:55 GMT";
}
Thu Oct 28 00:42:55 iPhone MyApp[11059] : Received memory warning. Level=1
Thu Oct 28 00:42:55 iPhone MyApp[11059] : -[__NSCFType tryLock]: unrecognized selector sent to instance 0x41bfd0
Thu Oct 28 00:42:55 iPhone MyApp[11059] : *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType tryLock]: unrecognized selector sent to instance 0x41bfd0'
*** Call stack at first throw:
(
0 CoreFoundation 0x30897ed3 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x3002f811 objc_exception_throw + 24
2 CoreFoundation 0x30899683 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
3 CoreFoundation 0x308411d9 ___forwarding___ + 508
4 CoreFoundation 0x30840f90 _CF_forwarding_prep_0 + 48
5 CoreData 0x316cc261 -[_NSSQLCoreConnectionObsever _purgeCaches:] + 124
6 Foundation 0x349bb6b3 _nsnote_callback + 142
7 CoreFoundation 0x3081e713 __CFXNotificationPost_old + 402
8 CoreFoundation 0x3081e3b3 _CFXNotificationPostNotification + 118
9 Foundation 0x349aadb7 -[NSNotificationCenter postNotificationName:object:userInfo:] + 70
10 Foundation 0x349b42d1 -[NSNotificationCenter postNotificationName:object:] + 24
11 UIKit 0x31ed9431 -[UIApplication _performMemoryWarning] + 48
12 UIKit 0x31ec7383 -[UIApplication _receivedMemoryNotification] + 126
13 UIKit 0x31ec72c7 _memoryStatusChanged + 42
14 CoreFoundation 0x3084e825 __CFNotificationCenterDarwinCallBack + 24
15 CoreFoundation 0x30835313 __CFMachPortPerform + 210
16 CoreFoundation 0x3082cce3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
17 CoreFoundation 0x3082cca7 __CFRunLoopDoSource1 + 166
18 CoreFoundation 0x3081f56d __CFRunLoopRun + 520
19 CoreFoundation 0x3081f277 CFRunLoopRunSpecific + 230
20 CoreFoundation 0x3081f17f CFRunLoopRunInMode + 58
21 GraphicsServices 0x31e445f3 GSEventRunModal + 114
22 GraphicsServices 0x31e4469f GSEventRun + 62
23 UIKit 0x31e51123 -[UIApplication _run] + 402
24 UIKit 0x31e4f12f UIApplicationMain + 670
25 MyApp 0x00052c81 main + 72
26 MyApp 0x00002f18 start + 52
)
I'm not really sure what core data was doing that it tried to obtain a lock from this object, however I feel like this is indicative of a threading issue somewhere inside my code.
Can anyone think of a good way to debug this or possible root causes?
I ran into this recently and found a solution. The bug is in Core Data itself, and manifests in versions prior to iOS 5.1 (it appears to be fixed in that version).
The crash happens when the persistent store coordinator (PSC) fails to load a given persistent store (say because the schema changed). In this case, the failed store still appears to be added to an internal Core Data cache, even though there is no external access to it. This cache is then flushed automatically by Core Data when the app is backgrounded, or in certain memory pressure situations. Everything is fine unless you the PSC that was used to try to load the failed store has since been deallocated, in which case the cache will try to access it and give the above error.
So, to summarize, you will hit this error in this situation:
Try and fail to load a persistent store from disk. This will likely happen because you've upgraded your app and the model schema changed.
Deallocate the persistent store coordinator you used to to try to load the store.
Background the app, or in some cases trigger a memory warning.
Crash
To work around this problem there are two options. I chose to simply not deallocate the PSC in the case of a failed call to -addPersistentStoreWithType:configuration:URL:options:error:, in which case the cache purge will still access a valid PSC. An alternative is to preemptively check that the model schema matches the on-disk persistent store's scheme using the following two calls:
+[NSPersistentStore metadataForPersistentStoreWithURL:error:]
-[NSManagedObjectModel isConfiguration:compatibleWithStoreMetadata:]
The second solution may avoid leaking a PSC in certain rare cases, but also assumes that the only possible way that a persistent store will fail to load is because of mismatched model schemas.
I actually found, after a bit of code analysis, the root cause of this appears to be crossing threads with CoreData. I had a background thread from an operation queue manipulating a NSManagedObjectContext which originated on the main thread (and caused a save! ouch!).
After a few of these manipulations if I sent a memory warning in the simulator the app would crash.

iPhone App Crashing during navigation

I have a tough problem (tough for me since I'm a newb.). I have a table view app that I'm working on. It starts with a table and you navigate down to a view controller. In that view controller I'm using some sample code hooked into a button that will add a contact to the iPhone address book.
My problem is when the user navigates back to the table of data, the app crashes. Is there any advice someone can provide? Or, maybe someone I could send me code for review?
Update*
Here's the information from the console.
[Session started at 2010-07-20 22:51:46 -0500.]
2010-07-20 22:51:49.621 Infinite Possibilities[5882:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSPlaceholderString initWithString:]: nil argument'
*** Call stack at first throw:
(
0 CoreFoundation 0x025ff919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0274d5de objc_exception_throw + 47
2 CoreFoundation 0x025b8078 +[NSException raise:format:arguments:] + 136
3 CoreFoundation 0x025b7fea +[NSException raise:format:] + 58
4 Foundation 0x0006869c -[NSPlaceholderString initWithString:] + 105
5 Infinite Possibilities 0x00003b90 -[RootViewController tableView:didSelectRowAtIndexPath:] + 3405
6 UIKit 0x0034c718 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
7 UIKit 0x00342ffe -[UITableView _userSelectRowAtIndexPath:] + 219
8 Foundation 0x00059cea __NSFireDelayedPerform + 441
9 CoreFoundation 0x025e0d43 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
10 CoreFoundation 0x025e2384 __CFRunLoopDoTimer + 1364
11 CoreFoundation 0x0253ed09 __CFRunLoopRun + 1817
12 CoreFoundation 0x0253e280 CFRunLoopRunSpecific + 208
13 CoreFoundation 0x0253e1a1 CFRunLoopRunInMode + 97
14 GraphicsServices 0x02e642c8 GSEventRunModal + 217
15 GraphicsServices 0x02e6438d GSEventRun + 115
16 UIKit 0x002e8b58 UIApplicationMain + 1160
17 Infinite Possibilities 0x00002834 main + 102
18 Infinite Possibilities 0x000027c5 start + 53
)
terminate called after throwing an instance of 'NSException'
Usually a crash means you have some sort of memory problem or calling a undefined function(sending a message that is not answered by the receiver).
Are trying to read from a pointer to an object that was released already?
Are you trying to send a message to an object that is not answering to it?
The good news is that you have a lot of good tools to find out exactly what it is:
First of all, open the console (Shift + Command R) and see if there is a message or stack trace when your app crashes. If there is no message, run the debugger (Shift + Command Y) and see where it stops on the crash.
Finally, if you see the status bar of XCode, it will tell you a bit of information about the crash (the message that was send about the crash, could be a EXEC_BAD_ADDRESS or some other thing.
Sadly, without your code or any of this information this is all I can do to help you. I would suggest not only copy and pasting but really understanding what that code is supposed to be doing and also learning how to debug your code.
For good resources I would recommend the Itunes U Standford Iphone development class and/or reading a good book about it(I read the Head First Iphone book and I love the series but didn't really like this one).

iphone iOS4 breaking app

I have an application that has been running fine since its launch over a year ago.
I developed it with iphone iOS 2.2.1 originally and tested and kept selling it up until 3.2 without issues.
Now it fails to launch with iOS4.
the app uses a non standard size for a UIPickerView (I don't think that's the problem but just mention it as you will see some complaint in the console output). It's also giving previously non reported NSAutoreleasePool warnings.
But the culprit seems to be when resizing the interface to the new iphone screen resolution (at least what I get from the console)
I know I have to do some research of my own but iOS4 has been out for so little and I have been very absorbed learning and developing my first app for android (so I have not tested this particular code, after a year+ this app only sells a few copies a day) that I thought it didn't harm to ask around here to check if someone has some info or has run into it already.
First, this is the console output when build and run with XCODE 3.2.3 and BASE SDK 3.2, runs without problem
2010-06-22 23:25:55.619 metalsandmaterials[82956:207] ******* Accessibility Status Changed: On
2010-06-22 23:25:55.710 metalsandmaterials[82956:207] ********** Loading AX for: xxxxxxxxx
But trying to run it with iOS4 gives this beauty:
2010-06-22 23:15:52.488 metalsandmaterials[80149:207] ******* Accessibility Status Changed: On
2010-06-22 23:15:52.546 metalsandmaterials[80149:207] ********** Loading AX for: XXXXXXX ************
2010-06-22 23:15:53.003 metalsandmaterials[80149:207] * -[NSAutoreleasePool release]: This pool has already been released, do not drain it (double release).
2010-06-22 23:15:53.005 metalsandmaterials[80149:207] * -[NSAutoreleasePool release]: This pool has already been released, do not drain it (double release).
2010-06-22 23:15:53.008 metalsandmaterials[80149:207] -[UIPickerView setFrame:]: invalid height value 50.0 pinned to 162.0
Right here! [UIIageView scale]
2010-06-22 23:15:53.011 metalsandmaterials[80149:207] -[UIImageView scale]: unrecognized selector sent to instance 0x5ac47a0
2010-06-22 23:15:53.013 metalsandmaterials[80149:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImageView scale]: unrecognized selector sent to instance 0x5ac47a0'
Call stack at first throw:
(
0 CoreFoundation 0x025f5919 exceptionPreprocess + 185
1 libobjc.A.dylib 0x027435de objc_exception_throw + 47
2 CoreFoundation 0x025f742b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x02567116 ___forwarding_ + 966
4 CoreFoundation 0x02566cd2 _CF_forwarding_prep_0 + 50
5 UIKit 0x0039a8e3 -[UIImageView setImage:] + 250
6 UIKit 0x0039b63e -[UIImageView initWithImage:] + 161
7 UIKit 0x05f286ce -[UIImageViewAccessibility(SafeCategory) initWithImage:] + 70
8 metalsandmaterials 0x0000bf09 -[TVCResults init] + 1841
9 metalsandmaterials 0x00002b8c -[UIVCalcHolder init] + 258
10 metalsandmaterials 0x00002758 -[CalcTestAppDelegate applicationDidFinishLaunching:] + 649
11 UIKit 0x002d759c -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1252
12 UIKit 0x002d99a1 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 346
13 UIKit 0x002e3452 -[UIApplication handleEvent:withNewEvent:] + 1958
14 UIKit 0x002dc074 -[UIApplication sendEvent:] + 71
15 UIKit 0x002e0ac4 _UIApplicationHandleEvent + 7495
16 GraphicsServices 0x02de1afa PurpleEventCallback + 1578
17 CoreFoundation 0x025d6dc4 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION + 52
18 CoreFoundation 0x02537737 __CFRunLoopDoSource1 + 215
19 CoreFoundation 0x025349c3 __CFRunLoopRun + 979
20 CoreFoundation 0x02534280 CFRunLoopRunSpecific + 208
21 CoreFoundation 0x025341a1 CFRunLoopRunInMode + 97
22 UIKit 0x002d9226 -[UIApplication _run] + 625
23 UIKit 0x002e4b58 UIApplicationMain + 1160
24 metalsandmaterials 0x000024ac main + 230
25 metalsandmaterials 0x000023bd start + 53
26 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
kill
kill
So this scale method is new to uiimageview? why wouldn't it work? has anyone run into this already?
ANY HELP IS EXTREMELY APPRECIATED
best regards
david
You get a message "xxxxxx does not recognize selector yyyyyy" usually when an object has been released but you are still trying to use it. At that point because the memory is random, the system thinks it's some other random kind of object (like UIImage). Thus it's a red herring, a sign that something else is wrong and you are over-releasing an object.
There's no way you are getting those weird autorelease messages unless you are doing SOMETHING with a custom autorelease pool. Fess up, what are you doing with an NSAutoreleasePool in your code?
I think they are probably related to the "does not recognize selector" messages since you may be over-releasing things because of this.
Well, for your first issue with the NSAutoreleasePool, I would use instruments so you can trace where the extra drains/releases are coming from.
Your second issue doesNotRecognizeSelector is telling you that the selector that is being called doesn't exist (or lost scope). I would use the debugger so you can, again, trace that code execution.
Ok, I left if at adding a -(void)scale to a subclass of UIImageView and using this new class. Tested it, works fine on 2.2.1, 3.2 and ios4, both on simulator, iphone touch 3g with ios4 and ipad with ios3.2.
I still need to get ahold of an iphone4 and see if some weird layout problem comes across (I still believe the problems appeared when the Os want to blow things up to the new retina display).
Not being in the US is going to make it a tad hard though
Could I be that you somewhere set the image property of an imageView to another UIImageView (as opposed to an UIImage)?
After all UIImageView does not respond to :scale, but UIImage does.