NSManagedObjectContext save doesn't crash but breaks on objc_exception_throw - iphone

I am having the same issue described at this address http://www.cocoabuilder.com/archive/cocoa/288659-iphone-nsmanagedobjectcontext-save-doesn-crash-but-breaks-on-objc-exception-throw.html
I am debugging an application that uses Core Data with multithreading, and I have a breakpoint on objc_exception_throw and it hits this breakpoint in the call to save. (line 2 in code)
NSError *error = nil;
[self.managedObjectContext save:&error];
if (error) {
NSLog(#"Error : %#",error);
}
I don't have any thing that is logged.
I am using Xcode 4 with ios 4.0 -> 4.3. I think this is not related to Xcode/iOS version.

Looking at this answer reveals that CoreData internally uses exceptions to manage their program flow. Thats why the debugger breaks at objc_exception_throw. As far as I know there is no way to disable this.
EDIT: Since then, there is now a solution to ignore these exceptions: Ignore certain exceptions when using Xcode's All Exceptions breakpoint
BTW: Do not check on error but use the returned BOOL value to ensure success of your save call. The correct way of doing this would be:
NSError *error = nil;
BOOL success = [self.managedObjectContext save:&error];
if (!success) {
NSLog(#"Error : %#",error);
}

First, when using multithread with CoreData I had few problems when
passing NSManagedObject around the app. Instead, as documented by
Apple, I end up passing NSManagedObjectID and reconstruct the full
object.
Second, when you don't have anything logged, it is likely related to
memory issues, try to run the profiler especially, but not only, looking for 'Zombie', it
should tell you more.
Finally, make sure you have initialized the context correctly, I had
similiar problem because the model from momd file was not found and
not loaded.

I had a similar problem, eventually it turned out to be because of an observer of NSManagedObjectContextDidSaveNotification that was deallocated without removing itself from the notification center. It seems that the CoreData exception "hides" the unknown selector exception that is raised when the notification center tries notifying whatever object occupies the memory freed by the registered (but deallocated) observer.

Recently I ran into the same issue: app crashing without any log, when trying to save managedObjectContext.
In my case there was a completely different cause from mentioned above:
Make sure you do not have DB Manager open on your mac, that could be locking the persistent data store.
This will (apparently) also kill the Core Date stack, without throwing any visible errors in code or in log.
Turned out I had some unsaved changes, which made the DB Manager lock the store. Closing the DB Manager fixed the issue. Simple and stupid error, but took me hours to figure out.

I happened to meet this problem, and after long time debug I found it's because of a duplicate declaration of the NSError* error, may you had another NSError* error in the outer scope, like:
NSError* error = nil;
Some code
if (!error)
{
NSError* error = nil;
// your code
}
Then the error will be nil although in fact there is a exception.

Related

Photomania- Stanford Paul Hegarty's class

is there something wrong with core data for xcode 4.3.2
I'm following the Stanford Paul Hegarty class for ios 5.0
doing the core data walkthrough (Video 14 Core data demo)
I downloaded the file here
I ran it in xcode 4.3.2 but the core data doesn't seem to work because the entries in the tableview do not appear.
I tried to run it in another computer with xcode 4.2 and ios 5.0
it's working perfectly
anybody who encountered the same problem? I'm pretty sure that xcode is at fault.
Interesting. I am having the same problems and I am also using XCode 4.3, but just thought it was because of the Flickr license that you need and which I don't have. (In FlickAPIKey.h, there is a #define FlickrAPIKey #"" and you won't download anything if you don't have that key.)
Update: I got myself a Flickr API key (you can just get one from their website) and tried the Photomania App on XCode 4.3: it works like a charm, so it looks like XCode is not your problem here. (Although on occasion I found that I had to stop and restart XCode to get rid of a strange bug or compiler error.) Anyway, maybe it is an idea to delete the data first before you try again: Just delete the App before you run it and the database file will get deleted as well.
Paul Hegarty after his class, has published an update version of his code which have a call to SAVE the CoreData database! This may be the reason why your CoreData informations doesn't persist.
His update note was:
// should probably saveToURL:forSaveOperation:(UIDocumentSaveForOverwriting)completionHandler: here!
// we could decide to rely on UIManagedDocument's autosaving, but explicit saving would be better
// because if we quit the app before autosave happens, then it'll come up blank next time we run
// this is what it would look like (ADDED AFTER LECTURE) ...
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
So, you have to Add the 'document saveToURL' line in the 'fetchFlickrDataInDocument' function like this:
- (void)fetchFlickrDataIntoDocument:(UIManagedDocument *)document
{
dispatch_queue_t fetchQ = dispatch_queue_create("Flickr fetcher", NULL);
dispatch_async(fetchQ, ^{
NSArray *photos = [FlickrFetcher recentGeoreferencedPhotos];
[document.managedObjectContext performBlock:^{
// perform in the NSMOC's safe thread (main thread)
for (NSDictionary *flickrInfo in photos) {
[Photo photoWithFlickrInfo:flickrInfo inManagedObjectContext:document.managedObjectContext];
// table will automatically update due to NSFetchedResultsController's observing of the NSMOC
}
// should probably saveToURL:forSaveOperation:(UIDocumentSaveForOverwriting)completionHandler: here!
// we could decide to rely on UIManagedDocument's autosaving, but explicit saving would be better
// because if we quit the app before autosave happens, then it'll come up blank next time we run
// this is what it would look like (ADDED AFTER LECTURE) ...
[document saveToURL:document.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:NULL];
// note that we don't do anything in the completion handler this time
}];
});
}
If someone is still facing the same issue using Objective-C, there is one more thing you need to do after getting API key: change all http:// to https:// within files in FlickrFetcher folder. This worked for me.

What causes "NSScanner: nil string argument"?

I got this message when I save data to core data.
NSScanner: nil string argument
I didn't use any NSScanner method. Where did it come from?
This is a bug? What should I do with it?
Thanks help, please.
From experience, I can say that -[NSDecimalNumber initWithString:] or +[NSDecimalNumber decimalNumberWithString:] with a nil string is one thing that causes that log message.
Set a breakpoint on -[NSScanner initWithString:] to start with; if you don't catch it that way, then break on the other ways you might create a scanner, like +scannerWithString: and -[NSConcreteScanner initWithString:]. That's how I flushed my unwanted log statement out.
FWIW, I had this message come out whilst building a core data app.
It was due to me rebuilding and running the app in the simulator, which effectively kills off your running process without going through any of your exit methods.
Depending on when / where you are saving your managed object context, you could be left with an incomplete managed object somewhere, then scanners which would expect to find values would have nothing when the app was relaunched and the half baked objects were returned from the store.
I have the same crash log NSScanner: nil string argument.
This is my sitution
Everything works fine on device.
Crash at dequeueReusableCellWithIdentifier only on simulator
I solved it by
Product->Clean Then rebuild.Every thing works fine for me. I not sure why this happened.
I had met this problem on iOS 9 and iOS 10 BUT iOS 11 work fine,I solved it by removing observer in dealloc where I had used KVO.
Such as:
- (void)dealloc {
[self.collectionView removeObserver:self forKeyPath:#"contentSize"];
}
I got this crash error but not about nil string issue.
My reason is that I use a cell in storyboard as dynamic but set Static Cells in the Attributes inspector. I changed that attribute to Dynamic Prototypes, solved the problem.

How to debug iPhone applications

how can i debug applications for iPhone in Objective-C, XCode
i mean ok, XCode and debug mode is fine, but when my application crashes on
BAD_ACCES (or smth. smilliar) i just get the trace to assembly
when iam debugging C++ and lets say want to access an invalid pointer, i get a trace right to the line of code where everything crashed... here i just get a trace to many internal functions in assembly, so i dont have a clue what and where went wrong
probably some release / retain problem, but how can i find out?
thank you
Here we go with the full answer:
I've had a look at your app and I think there is a problem with the combination of the UINavigationController and asynchronous http loading in two places. Enabling the zombies did reveal those two errer. The first on I was able to reproduce, the seconds one popped up several times and then not any more.
*** -[DetailViewController respondsToSelector:]: message sent to deallocated instance 0x56d6030
*** -[SearchViewController respondsToSelector:]: message sent to deallocated instance 0x56daa10
I've just throttled my bandwidth to see if those errors are connected to http requests. Look at [Throttling Bandwidth On A Mac][1] to set up a slow connection. I set it to 5KBytes/sec.
The first error occurs if you go very quickyl down to the details and then two levels up again and as a last action to trigger the error: click on search. The stacktrace shows a
#2 0x004545b8 in -[UIWebView webView:decidePolicyForMIMEType:request:frame:decisionListener:]
and there are some threads open, so looking at the dropdown, there is a webThread. Showing that thread reveals something going on with the webview loading the detailPages url. This hints that the webiew actually finished loading in a seperate thread and wasn't able to connect back to the webview itself [DetailViewController respondsToSelector:]. This can be easily proofed: remove the loading of the request for the webview: I wasn't able to reproduce the error.
Solution problem 1
The problem is easily fixed, as the webview is not released in the dealloc. Setting delegates to nil of objects is also recommended, but not needed in this case.
- (void)dealloc {
webView.delegate = nil;
[webView release];
}
The second error
The stackTrace shows a
CLLocationManager onClientEventLocation:
Solution error
Same as error 1, set the delegate to nil and release the locationManager.
When your app crashes you cann open up the debugger in the left hand window you can see the stacktrace. You can double click any line which will jump to correct position in your code(if the called method is of yours).
Goto Project->Edit Active Executable->Arguments Tab
Add the Variable in the lower window by clicking on +
Name:NSZombieEnabled
Value:YES
This tries to resolve memory addresses to class names for bad excess errors.
To find out about memory leaks, open Run->Run with performance tool->Leaks. This will open up instruments which is a brillant tool to find leaks.
Are you using XCode 3? If so, I would highly advise upgrading to XCode 4. The debugger in XCode 4 is brilliant in comparison. It let's you step back through the code and see exactly what caused the crash.

NSFetchedResultsController crashing on performFetch: when using a cache

I make use of NSFetchedResultsController to display a bunch of objects, which are sectioned using dates. On a fresh install, it all works perfectly and the objects are displayed in the table view. However, it seems that when the app is relaunched I get a crash. I specify a cache when initialising the NSFetchedResultsController, and when I don't it works perfectly.
Here is how I create my NSFetchedResultsController:
- (NSFetchedResultsController *)results {
// If we are not nil, stop here
if (results != nil)
return results;
// Create the fetch request, entity and sort descriptors
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Event" inManagedObjectContext:self.managedObjectContext];
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"utc_start" ascending:YES];
NSArray *descriptors = [[NSArray alloc] initWithObjects:descriptor, nil];
// Set properties on the fetch
[fetch setEntity:entity];
[fetch setSortDescriptors:descriptors];
// Create a fresh fetched results controller
NSFetchedResultsController *fetched = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"day" cacheName:#"Events"];
fetched.delegate = self;
self.results = fetched;
// Release objects and return our controller
[fetched release];
[fetch release];
[descriptor release];
[descriptors release];
return results;
}
These are the messages I get when the app crashes:
FATAL ERROR: The persistent cache of section information does not match the current configuration. You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'FATAL ERROR: The persistent cache of section information does not match the current configuration. You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:'
I really have no clue as to why it's saying that, as I don't believe I'm doing anything special that would cause this. The only potential issue is the section header (day), which I construct like this when creating a new object:
// Set the new format
[formatter setDateFormat:#"dd MMMM"];
// Set the day of the event
[event setValue:[formatter stringFromDate:[event valueForKey:#"utc_start"]] forKey:#"day"];
Like I mentioned, all of this works fine if there is no cache involved. Any help appreciated!
I had a similar problem with one of my apps, when the Apple released the new iOS 4.0.
Search:
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];
And set the value of the parameter cacheName to nil. It worked for me, hope it will for you. Let me know.
I started getting the same error when I upgraded by MacBook Pro to Snow Leopard 10.6.4 and the latest SDK.
As it turns out, many of us had been using code that wasn't in conformance with the rules, but we didn't know it because CoreData wasn't really behaving in accordance with its own rules.
Specifically, when you fetch things, they get cached, and in 4.0, that cache isn't automatically purged in cases where it was purged in the earlier SDK.
For me, the solution was simple. I just employed the class method that purges the caches. You can specify an individual entity, but I specify nil so it just does them all in this particular piece of start-up code:
[NSFetchedResultsController deleteCacheWithName:nil];
Suddenly, the little app I've worked on only to familiarize myself with CoreData is working again.
Straight from the documentation for NSFetchedResultsController:
Modifying the Fetch Request
You cannot simply change the fetch request
to modify the results. If you want to change the fetch request, you
must:
If you are using a cache, delete it (using deleteCacheWithName:).
Typically you should not use a cache if you are changing the fetch
request.
Change the fetch request.
Invoke performFetch:.
I encountered a similar problem.
When I inspected the Debugger Console, it showed what the cached objects and the fetched objects were so that I could figure out why they are inconsistent.
In my case it was due to a different predicate.
Since the values in my predicate are not dynamic, I could specify a different cache name for each predicate. That will create a cache for each 'type' I specify.
I suppose you will have to assess your need to have the cache. To specify nil, means that a fetch is made in every call.
I figured out that the error occurs only when the fetch request have some changes. If you are creating a new NSFetchRequest OR changing the predicate OR sort descriptor, then you should delete the cache or use a different cache. Otherwise, ensure that you have the same NSFetchRequest or make sure that your NSFetchedResultsController is retained and that should solve your problem.
If you're using the simulator, try resetting it--I'd guess you've changed your entity map and it's getting confused by a leftover cache. If not, you could try doing what the error says:
- (void)applicationWillTerminate:(UIApplication *)application {
[NSFetchedResultsController deleteCacheNamed:#"Events"];
//etc
}
The exception still occurs with Xcode 7 (beta 4):
You have illegally mutated the NSFetchedResultsController's fetch
request, its predicate, or its sort descriptor without either
disabling caching or using +deleteCacheWithName:
NOTE: This is with an unmodified Xcode "Template" Master-Detail iOS app with standard Xcode CoreData "boiler-plate" code created with Xcode 7 and using the latest (iOS 9) deployment target.
I noticed it first when I restarted my app in the simulator. I had been starting and stopping the app several times via Xcode and then it happened; and it kept happening. I decided to do some experiments, and the results:
Every time I stopped the app in the simulator, I would get the exception on a subsequent launch.
Every time I stopped the app using the simulator's Home button, I was able to launch it again successfully.
The issue can still be fixed as follows, using one or the other of the following methods:
In the AppDelegate's application didFinishLaunchingWithOptions method, add the following Swift NSFetchedResultsController.deleteCacheWithName(nil) or Objective-C [NSFetchedResultsController deleteCacheWithName:nil]; code. This clears out the corrupted cache.
In the Simulator, from the Simulator menu, select Reset Content and Settings. This fixes the problem, but you lose your test data.
I also believe that this is an artifact of running via Xcode and stopping the app prior to it being able to clean up. I've not seen this in the actual device.
Are you quitting the Simulator using the home button or by terminating the app in Xcode? Maybe the app isn't getting time to finish writing to the cache. Try using the home button to quit the app.
How many classes implement the same - (NSFetchedResultsController *)results method, do you use a different cache for each one? I was having the same issue and I think I fix it by using a different cache name fore some clases since I have different NSPredicates.
I was having the same problem. To fix, I put the [NSFetchedResultsController deleteCacheWithName:#"cacheName"]; before the init of resultsController. Works for me as he only goes there on the first time.
For those who run into the same problem nowadays, the problem is that somehow Core Data doesn't clean the cache so work fine at first time but doesn't after that. Then just put this line right after init the NSFetchRequest
[NSFetchedResultsController deleteCacheWithName:#"Name"];
I found via the Ray Wenderlich forums that
Note that it only crashes when the fetch request is not created yet when you add something new to the datastore, i.e. when the Locations view isn't loaded yet. If the view is loaded already, then it works fine. Odd, eh?
So, what happened in my case was this:
The normal launch process entails constructing an NSFetchedResultsController.
Because there are thousands of objects being fetched, a fresh fetch takes considerable time. To mitigate this, the fetch a) uses a cache, and b) happens in the background, allowing other activities to continue
Normally, though the UI is responsive and the user can do stuff, the fetch is complete long before the user might express a desire to create a new object.
However, sometimes the app will be launched in the background - say, from a WatchKit event, or a background fetch, etc) - and part of the launch will entail creating a new object in the datastore immediately.
If the new object was created before the fetch was complete, the app would crash.
The solution is to ensure that The fetch is complete before creating an object (which would affect the fetch).
Alternatively you could delete the cache, but that is less performant practically speaking.
Note that the admonition from the debugger that
You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:
simply does not capture this situation whatsoever, in that what you have changed was not the request, predicate, or sort descriptor, but rather more accurately could be described as having mutated the result set while the fetch was in progress.
It took me forever to track down this tiny piece of trivia. I hope you benefit.
NSFetchedResultsController *fetched = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"day" cacheName:#"Events"];
replace #"Events" with nil.

getting this exception [CFURL release]: message sent to deallocated instance 0x1049530 when debugging iPhone application

Title says everything.
I've enabled NSZombieEnabled for project.
cheers
Are you calling [justURL release] anywhere? You shouldn't, since it is autoreleased for you...
Just a shot in the dark (haven't bothered to test how it would behave), but are you certain that -URLWithString: is returning a value? Are you seeing the URL in the log after the NSLog?
If -URLWithString: doesn't like the URL (for example, if there's a space in it) then it will return a nil value, which -arrayWithContentsOfURL: might not like.
I did the exact same thing, e.g. calling [justURL release].. commented that and voila!
I had same problem and fixed it.
Firstly i create my url:
contentUrl = [NSURL URLWithString:step.Videolink];
and afrer i release it
[contentUrl release];
Its rough mistake, because NSURL URLWithString: create autorelease object.