Choi Taekyoon
Choi Taekyoon

Reputation: 1

How to instantiate an Array of class in swift?

Hey I gotta problem when I declared and created an array of my class.

I declared an array like this

var _mScoringData = [ScoringData]()

And here's 'ScoringData' class

class ScoringData{
    let num : Int!
    let question : String!
    var yes : Bool!
    var no : Bool!    

    init(num:Int,question:String){
        self.num = num
        self.question = question
        self.no = false
        self.yes = false
    }
}

I made a function to create an array of instances, following code is an implementation of the function

func createScoringDatas(){
    for var index = 0; index < scoreDataCount; ++index{
        _mScoringData.append(ScoringData(num:index,question: _mQuestionData.Questions[index]))
    }
}

Build was good however the array does not created and when I debugged nothing was on the heap. I want to know how to solve this problem.

thanks.

Upvotes: 0

Views: 2000

Answers (2)

Airspeed Velocity
Airspeed Velocity

Reputation: 40955

It’s impossible to tell without your full code, but chances are the reason is because your variable scoreDataCount is zero. If I take your code, and make sure scoreDataCount is non-zero, it works fine.

Is scoreDataCount just a count of the number of questions in _mQuestionData.Questions? If so, you may want to consider the following alternative to the C-style for and array subscripting:

for (index, question) in enumerate(_mQuestionData.Questions) {
    _mScoringData.append(ScoringData(num: index, question: question))
}

enumerate(someSequence) takes a sequence (such as an array), and creates a new sequence of pairs, an index starting at zero, and the elements of the sequence. You can then loop over that with for…in which can look a lot cleaner and help avoid bugs (like the one you’ve hit).

Once you understand this, it’s a short step from there to scrap the for loop altogether and replace it with a map:

_mScoringData = map(enumerate(_mQuestionData.Questions)) { 
  index, question in
    ScoringData(num: index, question: question)
}

Note, this creates a map, rather than appending to an existing one, so you may no longer need your initial creation line.

Whenever you have a sequence of things, and you want to transform each element and put it in an array, that’s a case for map. You could argue that the for…in is clearer (especially if you’re not used to seeing map) but the benefit of map is it makes it completely obvious what your intent is - to transform the input into a new array.

The other benefit of this is, you could now declare _mScoringData with let instead of var if it turns out you never need to change it once it’s first created.

P.S. you probably don’t need those ! after all the member variables in ScoringData. Those are creating implicitly unwrapped optionals, and are only needed in very specific circumstances. You might see them sometimes elsewhere when they’re needed but you don’t need to copy that on every member variable.

Upvotes: 1

Wayne Tanner
Wayne Tanner

Reputation: 1356

I'm not sure why you're seeing the problem you're having. I took the code and pasted it into a playground to run it and it works fine. I'm pasting my slightly modified version of the code below. My only changes were to declare the scoreDataCount value and to change the source of the questions to an array of strings.

class ScoringData{
    let num : Int!
    let question : String!
    var yes : Bool!
    var no : Bool!

    init(num:Int,question:String){
        self.num = num
        self.question = question
        self.no = false
        self.yes = false
    }
}

    let scoreDataCount = 5
    var _mScoringData = [ScoringData]()

    let questions = ["One", "two", "three", "four", "five" ]


    func createScoringDatas() {
        for var index = 0; index < scoreDataCount; ++index{
            _mScoringData.append(ScoringData(num:index,question: questions[index]))
        }
    }


createScoringDatas()
print(_mScoringData.count)
print(_mScoringData[2].question)

The last 2 print statements output 5 and "three" respectively which is what I would expect.

Upvotes: 0

Related Questions