0
votes

i have a Problem with a Class that createds some Questions for a TableView. There is a Class Question and a Class Questions, which hold an array of Question.

The Problem is, that the binding betweeen these classes are strong at the moment, and so the ARC could not dealloc the memory. Ive tried the Things described in the Swift Book about weak or unowned references, but i am not able to fix the leak in my Code.

Can anyone help me please, how to prevent Swift from creating a strong Relation between the Objects, so the ARC can dealloc the used Memory?

Thanks in Advance

class Questions {

var questions: [Question] = []

init() {

    let validJSONData = NSData(contentsOfFile : NSBundle(forClass:ViewController.self).pathForResource("data", ofType: "json"))
    let json = JSONValue(validJSONData)

    for item in json["questions"].array!
    {

        var rowhHeight:CGFloat = 44.00

        if(item["template"].string! == "textViewCell") {
            rowhHeight = 100.00
        }

        var newQuestion = Question(qIndex: item["qid"].integer!, qText: item["qtext"].string!, qTemplate: item["template"].string!, qHidden: item["hidden"].bool!, qRowHeight: rowhHeight)

        questions.append(newQuestion)


    }
}

func getQuestions() -> NSArray {
   return questions     
}

deinit{
    println("questionS deinitialized")
}

}

class Question: NSObject {

var qIndex: Int
var qText : String
var qTemplate : String
var qHidden : Bool
var qRowHeight : CGFloat

init(qIndex: Int, qText: String, qTemplate: String, qHidden: Bool, qRowHeight: CGFloat) {

    self.qIndex = qIndex
    self.qText = qText
    self.qTemplate = qTemplate
    self.qHidden = qHidden
    self.qRowHeight = qRowHeight
}

deinit{
    println("question deinitialized")
} 
}
1
Why do you say that you have a leak? I don't see a retain cycle as the Question object doesn't have a reference to the array. The array needs a strong reference to its elements. Releasing the Questions object will allow the elements to be released. - Paulw11
Thanks for your reply. Instruments tell me that i have a leak (for every Question Object) - When i check with Cylcles and Roots i find out "no ivar" as a leak for every Question in my Array. How do i relase a object in Swift? Set its value to nil? And why do i get a Leak - i want to work with my object, when should i release it? Little frustrating about Memory Managemet at the moment ;) - derdida
No iVar just means that instruments couldn't find an iVar that is pointing at the question (as you would expect because it is the array that is holding the reference). You can try Call Tree view, but I suspect that you don't have a problem - you are getting a false report from Instruments. In swift you release an object reference by setting it to nil, so you can try setting your questions array to nil as a test and you should see everything released. You can also confirm by adding a message to deinit as they show in the Swift book. - Paulw11
Ohhhh. You mean this "leak" isnt a real leak? The Call Tree is empty, so you mean if the call Tree is empty i dont have a real problem with a leak in my memory? That would be great news :) - derdida
That would be my guess. Testing by setting your array to nil would be a good way to confirm - the memory should be released. It could be something to do with Swift still being beta - maybe Instruments doesn't know about Swift arrays yet. - Paulw11

1 Answers

0
votes

may be cause because your model class will be create strong cycle reference with your Controller class hope this will solve your issue .

class Questions {

var questions: [Question]!

init() {
    questions = [Question]()
    let validJSONData = NSData(contentsOfFile : NSBundle(forClass:ViewController.self).pathForResource("data", ofType: "json"))
    let json = JSONValue(validJSONData)

    for item in json["questions"].array!
    {

        var rowhHeight:CGFloat = 44.00

        if(item["template"].string! == "textViewCell") {
            rowhHeight = 100.00
        }

        var newQuestion = Question(qIndex: item["qid"].integer!, qText: item["qtext"].string!, qTemplate: item["template"].string!, qHidden: item["hidden"].bool!, qRowHeight: rowhHeight)

        questions.append(newQuestion)


    }
}

func getQuestions() -> NSArray {
    guard let objQuestion = questions else{return NSArray()}
    return questions
}

deinit{
    println("questionS deinitialized")
}

}

class Question: NSObject {

var qIndex: Int!
var qText : String!
var qTemplate : String!
var qHidden : Bool!
var qRowHeight : CGFloat!

init(qIndex: Int, qText: String, qTemplate: String, qHidden: Bool, qRowHeight: CGFloat) {

    self.qIndex = qIndex
    self.qText = qText
    self.qTemplate = qTemplate
    self.qHidden = qHidden
    self.qRowHeight = qRowHeight
}
deinit{
    println("question deinitialized")
}

}