简体   繁体   中英

Compiling large array literal in Xcode 8.2

What is the best way to store a large multidimensional array with Swift?

I have a 4D array of integers that seems to have slowed down compiling in Xcode 8.2 now that its about 200 sets of 9 integers (1800 total). The first array is made up of 12 arrays, which then each has 8 arrays, which then each has 2 or more arrays, which are each made up of 9 integers. The thing is I plan to probably increase the amount to data by 5 or 6 times.

I couldn't compile my app last night and it finally worked this morning but it was still slow. I figure the problem will just get worse as I add to the array.

Some people say to just append each array in the viewDidLoad and some have mentioned loading the array for a txt file but I don't know how to do that.

I'm sorry to keep making the same joke, but you need to do this the same way Superman gets into his pants: one leg at a time. Start with the overall structure. Then keep making the innermost arrays and appending them into the outer arrays to build up the outermost array. This will get you started:

var level1 : [[[[Int]]]] = []
var level2 : [[[Int]]] = []
var level3 : [[Int]] = []
// -----
level3 = []
let innermost1 = [1,2,3,4,5,6,7,8,9]
let innermost2 = [11,12,13,14,15,16,17,18,19]
level3.append(innermost1)
level3.append(innermost2)
level2.append(level3)
level1.append(level2)
// ... keep going ...

In this way, we never need any big / deep array literals, and the project will compile easily.

Note too that the type of the array at each level is explicitly declared . This makes Swift a lot happier than having to infer it.

I like matt's one leg at a time approach but the alternative is to put it all in a file and load the file at start up. Here's how:

Create your file. JSON will probably do the trick

[
    [
        [
            [ 1, 2, 3, 4 ... ],
            [ ... ],

// etc

Let's assume it is called data.json . You need to make sure it is in your application bundle by adding it to the copy bundle resources build stage.

Somewhere near start up you need to retrieve the file from the bundle. I do it in a class that is defined in the bundle (the application delegate will do nicely) like this:

let myBundle = Bundle(for: type(of: self))
guard let fileUrl = myBundle.url(forResource: "data", withExtension: "json")
else
{
    // it's missing, bail out
}
guard let data = try? Data(contentsOf: fileUrl)
else
{
    // can't read it bail
}
guard let arrays = try? jSONSerialization.jsonObject(with: data)
else
{
    // invalid JSON, bail
}

At this point you have a nested structure of foundation arrays with the data you want. You might want to convert them into Swift arrays or not depending on what you want them for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM