How to Find the Source of an NSInternalInconsistencyException in an Xcode Stack Trace
This particular example doesn't give the developer much to go on. So, the answer to your question in this case is "Google it." Really, the best clue from the stack trace is the line:
[PFObject(Private) _deepSaveAsync:withCurrentUser:sessionToken:]
The line above indicates a failed save using currentUser
, combined with the error message "Tried to save an object with a pointer to a new, unsaved object." should be enough to point to a probable cause.
As it turns out, this error is not uncommon and is bewildering why Parse does not fix it. It is generally caused by when your app is using anonymous Parse users and it attempts to save an object prior to the user object having been saved. Since the user object has not been saved, it has no objectId
and the save of the other object fails.
The solution is to check to see if the currentUser
object has an objectId
, and if not, save it first before trying to write to Parse.
// Prevent race condition for unsaved user
// Courtesy of: http://samwize.com/2014/07/15/pitfall-with-using-anonymous-user-in-parse/
if ([PFUser currentUser].objectId == nil) {
[[PFUser currentUser] saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
//do stuff later
}];
} else {
//do stuff now
}
Swift 5.1 NSInternalInconsistencyException error
According to documentation, previousTrackCommand
selector should take MPRemoteCommandEvent
as first argument and return MPRemoteCommandHandlerStatus
:
func addTarget(handler: (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus) -> Any
So your handlePrevTrack
function should be declared as:
@objc func handlePrevTrack(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
...
}
TableView: How to proceed after catching 'NSInternalInconsistencyException'?
@synchronized(lock) solved my problem.
I just had to make sure that only one thread is able to manipulate the data source array at the same time. Now everything works fine, no more 'NSInternalInconsistencyException'.
Thx to trojanfoe and luk2302.
Exception is not being caught
Swift converts Objective-C methods with nullable returns and trailing NSError**
parameters to methods that throw in Swift. But, in Objective-C, you can also throw exceptions. These are distinct from NSError
s and Swift does not catch them. In fact there is no way to catch them in Swift. You would have to write an Objective-C wrapper that catches the exception and passes it back in some way Swift can handle.
You can find this in the Apple document Handling Cocoa Errors in Swift in the Handle Exceptions in Objective-C Only section.
So it turns out that you can catch it, but it is worthwhile considering whether you should (see comments from @Sulthan below). To the best of my knowledge most Apple frameworks are not exception-safe (see: Exceptions and the Cocoa Frameworks) so you can't just catch an exception and continue on as if nothing happened. Your best bet is save what you can and exit as soon as possible. Another issue to consider is that unless you rethrow the exception, frameworks such as Crashlytics won't report it back to you. So, if you did decide to catch it you should log it and/or rethrow it so that you know that it is happening.
How to fix 'NSInternalInconsistencyException' error using UICollectionView in Swift?
Your problem is caused by all of those guard/else
statements - If any of the guard
s fail then you return UICollectionViewCell()
- Which, as the exception says, is a cell that was not dequeued correctly.
Really, your data model should have been validated before it got to this point. products
should contain instances of Product
rather than a Dictionary
. This way you never load the invalid products into the data source array.
Once you do that you can simply write
var products: [Product]
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "productCell", for: indexPath) as! ProductCollectionViewCell
let product = products[indexPath.item]
cell.setProduct(product: product)
return cell
}
Remember that cellForItemAt:
may be called many times for a given item as the collection view scrolls - It should be as efficient as possible. Although there isn't a huge overhead in accessing the dictionary and creating the Product
there is no need to do it again and again.
Related Topics
"This Class Is Not Key Value Coding-Compliant" Using Coreimage
Location Access Request in iOS 11
Nil Cannot Be Assigned to Type Avcapturedeviceinput
Type 'Bundle' Has No Member "Module"
How to Fix Cannot Find 'Firebaseapp' in Scope
Bundle.Main.Path(Forresource... Always Returns Nil When Looking for Xml File
Create a Generic Swift Function to Return an Array of Core Data Entities
Filter on Calayer Except for a Shape Which Is an Union of (Non Necessarily Distinct) Rectangles
Can You Strict Generic Types or Give One Parameter More Than One Type
Should I Keep Extensions in Their Own "Extensions" File
What Was The Reason for Swift Assignment Evaluation to Void
Is There a Method to Check The UIcollectionview Item Drag Cancellation If The Item Wasn't Moved
How to Define a Variable in a Swift If Statement
Swift Increment Int! Not Working
Macos Security Scoped Url Bookmark for Folder
Editing a Package Dependency as a Local Package