0

I have a dictionary of type [String: Object], where MyObject is an array of AnotherObject. I need to have it sorted as I need to fill an UITableView with Keys.countnumber of sections and Object.count number of rows in each section. I put all the keys in an array, but when I try to append the values into another array I get Thread 1: EXC_BAD_ACCESS (code=1, address=0x8).

This is the code I'm using

var dictionary = [String: MyObject]()
var sortedKeys: [String]?
var sortedValues = [MyObject]()



func sortItems() {

        self.sortedKeys = self.dictionary.keys.sorted(by: >)

        let sortedDict = self.dictionary.sorted(by: {$0.key > $1.key})
        for (_, value) in sortedDict {
            print(value)
            self.sortedValues.append(value)
        }

    }

In the for loop, when I don't try to append the values to the array, it prints all the sorted values, the problem comes when I want to have them in an Array.

Edit

The dictionary is like this:

struct Object: Decodable {
    let elements: [AnotherObject]
}

struct AnotherObject: Decodable {
    let time, Id, Status: Int?
    let date, startTime, endTime: String?
}

dictionary: [String: Object]

So the keys are numbers (representing days) and every day has an Object with (at least) one anotherObject. I get the JSON from the API.

Thanks in advance

2 Answers 2

4

You should only sort the keys and then use that array to select from the dictionary and append your sortedValues array. I made the sortedKeys into a local variable

func sortItems() {
    let sortedKeys = self.dictionary.keys.sorted(by: >)

    for key in sortedKeys {
        if let obj = dictionary[key] {
            self.sortedValues.append(obj)
        }
    }
}

I don't know if this will make a difference in regard to the crash but another way is to let the function return an array

func sortItems() -> [Object] {
    let sortedKeys = self.dictionary.keys.sorted(by: >)
    var result: [Object]()

    for key in sortedKeys {
        if let obj = dictionary[key] {
            result.append(obj)
        }
    }
    return result
}

and then call it

self.sortedValues = sortItems()
Sign up to request clarification or add additional context in comments.

6 Comments

I still get the Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)
@ManuelLagunaMatias I can only assume this is because of something that happens elsewhere in your code. What other part of your code modifies the array? You say that MyObject is an array of AnotherObject, what does that mean?
I edited my comment... I don't know what can be happening, but the array is only being used in this method at the moment...
When is the decoding happening and is it asynchronous? I am wondering if the sort might happen while items are being added to the dictionary?
in viewWillAppear I make the api call, and right after inside the completion handler I call sortItems . As I said, if I print the values there's no problem. Problem comes when appending to array
|
2

You don't use sortedKeys at all and the result of sorting a dictionary is an array of tuples so the dictionary enumeration syntax for (key, value) in is wrong

Probably you want this

func sortItems() {

    let sortedKeys = self.dictionary.keys.sorted(by: >)

    for key in sortedKeys {
        let value = self.dictionary[key]!
        print(value)
        self.sortedValues.append(value)
    }
} 

Force unwrapping the value is 100% safe as the key clearly exists.

3 Comments

I still get the Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)
That's rather impossible as there are no optionals involved.
so we still don't know where the problem is but it's happening.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.