I am in a strange situation . when i try to reload the tableview using reloadData() it shows the following error . . .
fatal error: unexpectedly found nil while unwrapping an Optional value
Here is the web service method that retrieves output
func didRecieveOutput(results:NSArray) {
if results.count != 0
{
userOrders = results as! NSMutableArray
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.orderList.reloadData() })
}
}
Edit : I had checked my connection as well as delegate & datasource . It works fine with static data . But problem came when I called reloadData(). I had the same problem with static data as well as dynamic (data from server).
There could be n number of reasons for this error. Some of the common causes are:
Your #IBOutlet for your UITableView is not properly connected.
Missing Delegate/Datasource could also be a reason.
Your model that feeds data to table views is being modified just before reloadData() call.
You are not properly checking for nil before using some objects.
Post getting server response, you are creating a new instance instead of using the one that was already loaded.
Another reason could be if your view structure is like this: UITableViewController ---> UIView ---> UITableView, then 'tableView' goes nil and you need to call out [[self.view.subviews objectAtIndex:0] reloadData];. Reference: Apple Discussion Forum.
You can try above cases but for us to pin point the error you would need to share your table view rendering code and flow.
Solution found !!!!
:)
Thanks to Abhinav for giving me the thread even though his suggestion failed.
var array : NSArray = self.view.subviews
array.objectAtIndex(0).reloadData()
I got the same error for this also.
So I tried this and worked
var array : NSArray = self.view.subviews
array.objectAtIndex(2).reloadData()
Here in this array my tableview is at 2nd index. So my suggestion is to check the array to identify the tableview object first and use the index.
Related
Working on a new project, our team decided to use UICollectionViewDiffableDataSource to handle our collection views. It works fine, but we're getting (infrequent) crashes logged via an online tool with the message Invalid parameter not satisfying: initialSnapshot.numberOfSections == initialSections.count. We can't seem to reproduce this locally.
The crash occurs at the point where we update the data source with new data, specifically at dataSource.apply(snapshot). We're unsure as to how this could happen, as the data is always created the same.
Specifically, the unit working on this one view decided to forgo the creation of a section model and instead decided to use an Int as section identifiers, because they didn't want to use sections, just display items. That's one thing I hadn't seen before, but an Int satisfies the requirements for identifiers, so the code does compile correctly.
Here is the code:
Collection View and Data Source creation
These variables are inside the class of a UIView which is programmatically created.
var collectionView = UICollectionView(frame: .zero, collectionViewLayout: createCollectionViewLayout())
lazy var dataSource = UICollectionViewDiffableDataSource<Int, URL>(collectionView: collectionView, cellProvider: provideCell(_:indexPath:item:))
Updating the Datasource
func updateUI() {
var snapshot = dataSource.snapshot()
snapshot.deleteAllItems()
snapshot.appendSections([0])
if let urls = viewModel?.imageUrls {
snapshot.appendItems(urls)
}
dataSource.apply(snapshot)
}
In all (production) cases I have tested, viewModel?.imageUrls is empty on the first call, then contains items on the second call and all calls after that. The number of items usually doesn't change.
I have thought about not using dataSource.snapshot() and instead creating a new one, then I also wouldn't have to call deleteAllItems() every time. But I don't want to just push this as the solution when I can't be sure whether this really fixes the issue.
Has anyone encountered an issue like this before? Is it correct to use an Int as the section identifier? What could be other causes of the crash?
My guess is that you delete only items and each time you add an additional section to your snapshot, which causes an error.
So if your Snapshot already has a "0" section, you do not need to add a new one each time.
In my projects I create a new snapshot every time:
var snapshot = NSDiffableDataSourceSnapshot<Int, URL>()
snapshot.appendSections([0])
if let urls = viewModel?.imageUrls {
snapshot.appendItems(urls, toSection: 0)
}
customDataSource.apply(snapshot, animatingDifferences: animate)
The same approach is used in WWDC videos.
The way I currently have my code arranged, the following line will run for various managed-object-contexts. Some of the fetched entities will have "complededDate" and others will not have a "completedDate" attribute.
let task = retrieved_MgObjCntxt[(indexPath as NSIndexPath).row]
if let itemFinDate = task.value(forKey: "completedDate") {
...
I thought by using if-let, that if this failed then it'd be okay... but I'm getting an "lldb" crash. I've been playing with trying to solve it using do/catch and throw but I'm not super familiar with how those work.
Is there a way to safely check so that if "completedDate" doesn't exist, it just skips the code within the if-closure??
let task = retrieved_MgObjCntxt[(indexPath as NSIndexPath).row]
if task.entity.propertiesByName.keys.contains("completeDate") {
...
}
You can find all the keys for you objects entity type by using:
managedObject.entity.attributesByName
And then see if that dictionary's keys contains "completedDate"
TLDR: I'm getting an EXC_BAD_ACCESS error using swift in XCode 6.1 building for iOS8.1. I believe the issue is likely a compiler error.
I am making an app wherein the user is allowed to add (Korean) words from a dictionary (in the English sense) to a word list. I have the following classes that define a word (with associated definitions, audio files, user-interaction statistics, etc.) and a word list (with an associated list of words and methods to add/remove words to the list, alphabetize the list, etc):
class Word: NSObject, NSCoding, Printable {
var hangul = String("")
var definition = String("")
// ...
}
class WordList: NSObject, NSCoding {
var title = ""
var knownWords = Dictionary<String,String> ()
// ...
func addWordToList(wordName: String, wordDefinition: String) {
// Debug statements
println("I am WordList \"\(self.title)\" and have the following knownWords (\(self.knownWords.count) words total): ")
for (_wordName,_wordDefinition) in self.knownWords {
println("\t\"\(_wordName)\" : \(_wordDefinition)")
}
println("\nI am about to attempt to add the word \"\(wordName)\" with definition \"\(wordDefinition)\" to the above dictionary")
// Add word to wordList, including the 'let' fix
fix_EXC_BAD_ACCESS_bug()
knownWords[wordName] = wordDefinition // EXC_BAD_ACCESS
}
func fix_EXC_BAD_ACCESS_bug() {
// This empty line attempts to solve a exc_bad_access compiler bug when adding a new value to a WordList dictionary
let newDic = self.knownWords
}
// ...
}
Next I have a UITableViewController with a UISearchBar that I use to display the dictionary (again in the English sense) of words to the user. The user adds words by tapping a button (which is displaying an image) on the right of each cell, which calls the #IBAction func addWord() in the viewController:
class AddingWordsToWordList_TableViewController: UITableViewController, UISearchResultsUpdating {
var koreanDictionary = KoreanDictionary() // Custom class with method 'getWord(index: Int)' to return desired Word
var filteredSearch = [Word]()
// ...
// Add word
#IBAction func addWord(sender: UIButton) {
// Add word
if self.resultSearchController.active {
let word = filteredSearch[sender.tag]
wordList.addWordToList(word.hangul, definition: word.definition) // Enter addWordToList() here
} else {
let word = koreanDictionary.getWord(sender.tag)
wordList.addWordToList(word.hangul, definition: word.definition)
}
// Set image to gray
sender.imageView?.image = UIImage(named: "add133 gray")
// Save results
wordList.save()
// Reload table data
tableView.reloadData()
}
// ...
At first the app compiles and seems to run fine. I can add a new word list and start adding words to it, until I add the 8th word. I (always on the 8th word) get a EXC_BAD_ACCESS error in (WordList) addWordToList with the following println information:
I am WordList "School" and have the following knownWords (7 words total):
"방학" : school vacation
"대학원" : graduate school
"학년" : school year
"고등학생" : high school student
"초등학교" : elementary school
"학생" : student
"학교" : school
I am about to attempt to add the word "대학생" with definition "college student" to the above dictionary
Note that the order in which I add the words appears irrelevant (i.e. the word "college student" can be added successfully if it is one of the first 7 words). There is nowhere in the code where I explicitly change behavior based on the number of words in a word list (except to display the words in a word list as cells in a UITableView), or any dependencies that would (to my knowledge) make the 8th word a special number. And indeed this number can change by using the let hack= solution (see below) to a different number, but for a particular build is always the same number.
At this point I'm at a complete loss of what to do. I'm relatively new to swift and have spent quite a few hours looking up how to fix exc_bad_access errors. I've come to the following point:
It seems exc_bad_access errors usually mean one of three things (http://www.touch-code-magazine.com/how-to-debug-exc_bad_access/)
An object is not initialized
An object is already released
Something else that is not very likely to happen
I don't feel like either 1 or 2 can be the case for me, as right before we get the access error we can print out the contents of the dictionary in question (knownWords). However, as is always the case it is highly likely I'm missing something obvious, so please let me know if this is indeed true.
If the error is caused by 3 above ("something else") I have tried the following:
(From EXC_BAD_ACCESS on iOS 8.1 with Dictionary and EXC_BAD_ACCESS when updating Swift dictionary after using it for evaluate NSExpression solutions)
I have tried different variations of the let stupidHack = scenario, and it does sometimes change the results, but only the number of entries allowed before crashing (i.e. I can sometimes get to the ~15th/16th entry in the dictionary before the error). I have not been able to find an actual, bug-free solution using this method, however.
I have rebuilt using both Release and Debug modes; the error appears in both. Note I am only using the simulator and do not have a developer's license to try it on an actual device.
I have turned off (set to "None") compiler optimization (it was already off for the Debug build anyway).
I have tried building to iOS 8.0 with the same error results.
Any way to get around this issue is appreciated. A let hack = solution is acceptable, but preferably a solution will at least guarantee to not produce the error in the future under different build conditions.
Thanks!
Im trying to query my Parse User database in order to create a friend request between two users. The user inputs a user name that they want to add as a friend. However, when I try to query the database, I get a "EXC_BAD_ACCESS" error on the line where I am adding the condition. Not sure why Im getting this error, as its my understanding it has to do with trying to access memory already freed. Anything that you can do to help would be very appreciated!
var friendship = PFObject(className: "Friends")
var findUser:PFQuery = PFUser.query()
findUser.whereKey("username",equalTo:username2) //program crashes here for some reason
findUser.getFirstObjectInBackgroundWithBlock {
(user2, error: NSError!) -> Void in
if user2 == nil {
println("Failure")
} else {
println("Successfully retrieved the object.")
friendship["user1"] = PFUser.currentUser().objectId
friendship["user2"] = user2.objectId
friendship["pending"] = true
friendship.save()
}
}
Set a breakpoint in the compiler and navigate the steps until you hit the crash so you can understand exactly at which point it crashes a troubleshoot further from there with the better understanding.
Also once it has crashed use LLDB print out po ivar to check if any of your ivars got instantiated and which ones are empty or execute dubious functions with exp func.
So... It works today. Not sure what happened. Co-Developer and I reorganized frameworks and everything works fine now. Thank you for your help everyone. I appreciate the responses :)
I have created an iOS app using Swift and everything is working fine and dandy on the simulator. I get no errors or crashes at all, but when I submit my app to put up on the app store Apple rejects it and lets me know that it crashes when the user makes a selection. I cannot recreate this error/crash. I took the crash logs and symbolicated them. This line of code came up as the culprit for the crashes:
linksToPass = getLinks(season) as [String:[String]]
This line is trying to store the resulting Dictionary from the getLinks() function I created. It for sure is getting a dictionary and if there is no dictionary to send back I create a dictionary which has error information in it, so it is for sure returning a dictionary in that format no matter what. Seeing as I cannot recreate the crash, I am just trying to error check this line of code in any way possible so it does't crash when I resubmit to Apple.
I tried checking if the resulting dictionary was nil like so:
if(getLinks(seasons) != nil){
linksToPass = getLinks(season) as [String:[String]]
}
This is not valid though, and XCode lets me know that UInt8 is not compatible with NSDictionary or something of that nature.
I then fixed that line and changed it to this:
if(getLinks(seasons) != ["":[""]]){
linksToPass = getLinks(season) as [String:[String]]
}
I am just not sure if this is even a good way to check for errors. I was wondering if there were any suggestions on how I may go about making sure this line does not fail and result in a crash. Thank you very much.
EDIT:
Here is my getLinks() function if that helps add more info to the problem:
var season = ""
let hymn_links = Hymn_Links()
func getLinks (nameofseason:String) -> NSDictionary
{
switch (nameofseason)
{
default:
return ["Maps Not Found": []]
}
}
EDIT #2:
This is my updated getLinks() function with the use of optionals.
func getLinks (nameofseason:String) -> NSDictionary?
{
switch (nameofseason)
{
default:
return nil
}
}
Also in my statement of linksToPass I changed it to:
if let links = getLinks(season) as? [String:[String]]
{
linksToPass = links
hymnnames = [String] (linksToPass.keys)
}
There are some known issues with the Swift optimiser. Some people have resorted to shipping with debug builds.
My suggestion would be to test with an optimised build to see if you can reproduce it. You can then try shipping a debug build to the App store.
General Code Comments
Why are you returning an NSDictionary rather than a Swift dictionary anyway? Without knowing the contents and creation method for your hymn_links object I can't be sure how good it is.
I would avoid as casts until Swift 1.2 and stick to using as? and then handling the nil case. At least in your "Edit 2" a nil will cause a crash as nil cannot be cast to [String:[String]] although [String:[String]]? should be possible.
Can you guarantee that all of the items returned by the switch statement will never under any circumstances be nil? If not getLinks should return an Optional.
Note that is is virtually impossible for getLinks to know that one of the items will never be nil and in Swift un-handed nils are a crash waiting to happen. Unless all these methods correctly handle nil.
Return an Optional and handle that in the statement that calls getLinks.
Languages handle nils differently, Objective-C handles them rather well, Java and Swift by crashing. But Swift has a mechanism to handle nils without crashing: Optionals, use it.