i've been building an app since 1 month using NSFetchedResultsController and i was testing the app on the 3.1.2 SDK. The poblem is that i've been using NSFetchedResultsController everywhere in my app and was working on the 3.1.2 version of the SDK, now my client say that i should make it compatible with the 3.0 version and the deadline is almost there.
But is crashing everytime i change an object handled by the contoller, the application is crashing with very weird errors.
The problem occure when removing the last object in a section and when a change make an object love to another section.
I've been using a sample code from "More iPhone 3 Development Tackling iPhone SDK 3" by Dave Mark and Jeff LaMarche. I've also included some changes from link text
Here is a sample output of the console when the application is crashing.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (2 inserted, 0 deleted).'
2010-03-14 16:23:29.758 Instaproofs[5879:207] Stack: (
807902715,
7364425,
807986683,
811271572,
815059090,
815007323,
211023,
4363331,
810589786,
807635429,
810579728,
3620573,
3620227,
3614682,
3609719,
27337,
810595174,
807686849,
807683624,
839142449,
839142646,
814752238
)
If i knew that NSFetchedResultsController is so buggy, i would never used it.
So basicaly i need the my NSFetchedResultsControllerDelegate to work fine on the 3.0 and above SDKs.
It would be life saver if someone help me figure out what i'm doing wrong.
It appears from your error messages that you are inserting sections into the table when you should be deleting them. Your tableView dataSource is only supplying one section after the updates even though you have told the tableView to expect a total of four sections.
I don't think this is a case of NSFetchedResultsController being buggy, but rather that it is tricky to implement outside of simple use cases. Your crashes are almost certainly occurring as a result of your controller:didChangeObject:atIndexPath:forChangeType:newIndexPath delegate method. The key to successfully implementing this method (at least in my experience) is to keep in mind that the changeTypes are both object and indexPath driven. This makes "updates" and "moves" tricky conceptually.
Consider the situation where a managed object is changed such that it sorts under a new sectionNameKeyPath. Conceptually, we think of the object as having "moved" to a new section since the fetchedResultsController now sorts it under a new heading in the tableView. If the object's indexPath does not change, however, the fetchedResultsController considers this an "update" and not a "move".
What's worse is that even though the managed object that changed still retains the same indexPath, other objects in the fetchedResultsController may now have new indexPaths because they were bumped around by the change. This means that you will have to manually handle section insertions and section deletions in the "update" section of your delegate method. Similar problems will need to be addressed in the "move" section of your delegate method.
Without trying to explain it in so many words, LaMarche's fix is attempting to address this problem in a generic way that accommodates as many use cases as possible. By trying to understand the problem as it pertains to your use case, you may be able to significantly reduce the complexity of the code that LaMarche uses. Focus specifically on the "update" and "move" sections of your delegate method, as these are the most likely culprits for your problem.
Check out this resource:
http://iphonedevelopment.blogspot.com/2009/11/i-know-youre-tired-of-hearing-about.html
Helped me tremendously.
Related
I've recently been playing around with OSX programming (usually an iOS guy) but I've hit a strange issue with NSCollectionView that I just can't seem to debug.
When I change the data that my data source uses to populate the collection with items, I call reloadData() on the collection view as usual and sometimes hits an assertion. The error I get is Parameter indexPath out of bounds or nil. If I don't change the data the app always crashes at the same point(s) though sometimes, usually the first time, it works just fine and only crashes subsequently.
Now, I've debugged this numerous times. The data is correct and at no point in my code do I ever see a nil index path. The assertion always occurs on the makeItemWithIdentifier call, and always on the last item in the collection. If I continue, I either see what I expect or else some of the cells from the previous collection are still there behind the new cells.
At one point I refactored the code slightly and found the error occurring in NSCollectionViews itemAtIndexPath: function instead.
Has anyone else seen this error and, if so, what caused it?
Update 2: I now know what is causing this issue, but have no idea how to prevent it. What happens is this: the user clicks an item in the collection view. That item changes the data object that the data source is reading from calls reloadData during the collection view delegate's didSelectItemsAtIndexPaths method. For some reason, after execution of this method, the collection view is queried again for the cell with that index path. If the table has been reloaded in the meantime then that cell is gone, leading to the exception. In short: you can't call 'reload' on a collection view while a mouse event is being processed on one of its cells without getting an annoying assertion. So if anyone can think of a way around this issue, I'd love to hear it!
My app is hanging during search in a table view.
For what it's worth, the view hierarchy is very complex, there are popovers involved as well as filters and search bars etc. I am reviewing all those possibilities.
But the non-crash - it's an infinite loop - occurs when the search results table is being displayed / updated, after a call to reloadData.
Here is what I get when I stop the program and look at the main thread:
You can see - it involves UIView, CALayer, CATransaction. I have no clue how to get back to my controller classes to find the offending code.
Any hints, suggestions, wild guesses welcome!
EDIT Here is more - some more classes appearing when I interrupt at some other random point.
This is an old question, but in case other folks arrive here: it's possible you're facing a layout feedback loop. I wrote an article about how to debug these (link: Debugging Auto Layout feedback loops) but here's a summary:
If you modify your layouts during layout, or if you have ambiguous layout, you might find yourself stuck in a loop.
Apple discussed a special debugging technique at WWDC 2016 – skip to about 15 minutes before the end, and they introduce the layout feedback loop debugger.
To try it yourself, add -UIViewLayoutFeedbackLoopDebuggingThreshold 100 to the list of launch arguments for your app, then run it again.
When the error happens next time, you should get (a lot of) debugging information that helps point you in the right direction.
I have an issue running an app on a simulator.
The problem:
EXC_BAD_ACCESS occurring at objc_msgSend in Thread 1.
Screenshot :
In my Application, I have multiple ViewController. when I click on back button of UINavigationBar then this type of issue is generated, I can't explain my problem because all the functionality works properly.
Example :-
1 - fitstVController (work properly)
=> it have UITableView, when I click on specific row then it will go on another UIViewController (SecoundViewController)
2 - SecoundViewController (work properly)
=> it have UITableView and UIActionSheet. when I select button of UiActionSheet then another UIViewController (ThirdViewController) is open
3 - ThirdViewController (work properly)
=> it have UITableView and multiple UIPickerView. But HERE IS PROBLEM THAT I CAN'T GO BACK AT PREVIOUS UIViewController (SecoundViewController).
=> when i do that then EXC_BAD_ACCESS (Code = 1, address = 0x30000008) issue generated.
In short, this type of problem occurs when you release the memory assigned to an object that has been already released. Most likely, this type of issue is generated when you go back to your previous UIViewController (or other cases).
And also, I suggest reading the following link for a more thorough explanation:
Hamster Emporium archive:So you crashed in objc_msgSend()
Setting an exception breakpoint means that Xcode will stop execution as soon as an exception is raised. It's not entirely foolproof, but this will usually result in the app breaking on the line of code that caused the problem.
That makes it a LOT easier to track down the source of the problem - although the stack trace is the definitive way of diagnosing issues, it's often far too detailed to be of much use (especially if like me you're not a compiler expert.)
To set this up, click on the Breakpoints symbol in the Navigator panel and click the + button at the bottom. Then select Add Exception Breakpoint, and Objective-C from the List of choices.
As #TimD has rightly pointed out, you can set an exception breakpoint and it will highlight the offending line of code (rather than trying to decipher the assembler or manually trying to identify where the problem is). And, as always, when diagnosing these sorts of memory issues, you should always enable zombies. Finally, especially important in non-ARC code, you should run your code through the static analyzer as many memory related problems can be identified there. You should always make sure you have zero warnings from the static analyzer as it invariably points out critical programming errors.
I have a core data model with a parent item and child items under it. In Xcode 3, when I generated the NSManagedObjects for this, I had methods called addChildsObject object method on Parent, but this has gone away in Xcode 4 (see Xcode4: Different code generated for custom core data managed objects). My question is this: how should I be adding the children to the parent now? I really don't want to mess with the generated code, revert to using Xcode3, or add a category to Parent to bring back the missing methods. Is there an approved way, or did Apple just muck up the whole process?
After discovering and reviewing the documentation on Dynamically-Generated Accessor Methods, it appears that Apple still recommends using the now non-existent methods, so it would appear that they have just screwed up by removing them. There is, however, another recommended way of doing this:
NSMutableSet *children = [parent mutableSetValueForKey:#"child"];
[children addObject: child1];
[children removeObject: child2];
This is not fabulous, because it relies on an unchecked string name, but it's the only remaining recommended way to do this without custom implementations. Thanks a lot Apple!
While searching a bug in my code today I found a strange thing. When inspecting a UIView instance in the debugger the variable view of Xcode does not show the subviews member of the UIView class.
I only see this fields in the debugger (> should indicate the opening triangle):
UIResponder
_layer
_tabInfo
_gestureInfo
_touchData
_charge
_tag
_viewFlags
I'm missing the _subviews member and come to think of it also all the positional members (at least one of them should be there).
Does anybody know what I'm missing or doing wrong (as far as I can tell it is not a problem as a google search for this problem didn't got me any results).
I use Xcode version 3.1.3 with:
XcodeIDE: 1191.0
XcodeCore: 1192.0
XcodeSupport: 1186.0
on a mac with OS 10.5.7 and iPhone SDK 2.2.1 (I also tested with iPhone SDK 3.0).
I hope somebody knows anything about this. It gives me a little strange feeling that I cannot trust the debugger to show me everything I should know for debugging a problem. And it's not good if you need to mistrust you tools :(
The debugger is only going to be able to show you members, not properties. Remember that the two are different in Objective C. A property is just syntactic sugar for a setter and/or a getter. So the read-only "subviews" property of UIView only guarantees that it has an implementation for this method:
- (NSArray *)subviews;
As you've noticed, Apple has implemented many of their properties using undocumented member variables that resemble their corresponding property names, but with leading underscores. This allows you to spy on the internals of some objects to see what's going on in some cases, but many properties aren't implemented in such a transparent manner. In these cases, you'll need to inject some diagnostic code into your app to access the property and output its return value using NSLog, and/or store the value in a temporary variable that you can observe in your debugger.
Don't blame the poor debugger. It's doing exactly what it's designed to do. If it helps, you can blame properties for trying to trick us into thinking they're member variables when they're really methods.