3

I'm trying to receive mutable variable from my array, but something goes wrong. Question in code.

var baloonsArray = NSMutableArray()

override func didMoveToView(view: SKView) {
        var baloon = SKSpriteNode(imageNamed: "baloon") //"Variable "baloon" was never mutated; consider changing to "let" constant"
        baloon.xScale = 0.1
        baloon.yScale = 0.1

        ballonsArray.addObject(baloon)
        addChild(baloon)
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    for touch in touches {
        for var baloon in baloonsArray {
            baloon.xScale = 0.2 //Here xcode telling me: "Cannot assign to property: "ballon" is immutable". But i declared him as var. With Objective-C there was no problems. What should i do? 

        }
    }
}

When Im trying to change baloon xScale in touchesBegan function xcode telling me: "Cannot assign to property: "ballon" is immutable". But i declared him as var. With Objective-C there was no problems. What should i do?

2
  • Please don't ask your question in the code as it's hard to see it. Commented Oct 5, 2015 at 20:15
  • 1
    please check this link: stackoverflow.com/questions/28674399/… Commented Oct 5, 2015 at 20:26

2 Answers 2

2

The problem is your use of NSMutableArray. To Swift, it is opaque. That is, Swift doesn't know what is in it. But Swift has strict typing. So it doesn't know what properties its elements have, and it isn't going to let you assign to a property it doesn't understand. So if you really want to use NSMutableArray, you must cast its elements when you fetch them, so Swift knows what they are:

for baloon in baloonsArray {
    let baloonsprite = baloon as! SKSpriteNode
    baloonsprite.xScale = 0.2
}

That works. However, it would be better not to use NSMutableArray in the first place. Instead, declare baloonsArray as a mutable Swift array:

var baloonsArray = [SKSpriteNode]()

That takes care of the problem in a much neater way. Now Swift knows what is in this array - it is SKSpriteNode objects. And Swift knows that it is okay to assign to an SKSpriteNode's xScale.

You need to get used to Swift's strict typing, including the fact that the elements of an array are typed.

Sign up to request clarification or add additional context in comments.

1 Comment

Ops... I didn't see the update in your answer. I repeated the same concept in my own answer :)
1

Point 1

In the following code you are defining a variable balloon.

This variable exists until it goes out of scope at the end of the method, just an instant before the }.

override func didMoveToView(view: SKView) {
    var balloon = SKSpriteNode(imageNamed: "baloon") //"Variable "baloon" was never mutated; consider changing to "let" constant"
    balloon.xScale = 0.1
    balloon.yScale = 0.1

    ballonsArray.addObject(balloon)
    addChild(balloon)
}

Now, this variable refers an object of type SKSpriteNode. This means that the variable is a pointer, more specifically it contains a number that is the address of the sprite inside the heap.

If you change some property of the sprite you are not changing the variable, infact the variable balloon still contains the address of the sprite into the heap. So you are not mutating it.

The only way to mutate the variable balloon is assigning it to another SKSpriteNode. You are not doing it so the warning correct.

Point 2

The matt's answer is totally correct.

You could also consider not to use NSMutableArray. The Swift native array is much better and does support generics. So you can avoid a cast.

class Scene : SKScene {

    var ballonsArray = [SKSpriteNode]()

    override func didMoveToView(view: SKView) {
        let balloon = SKSpriteNode(imageNamed: "baloon")
        balloon.xScale = 0.1
        balloon.yScale = 0.1
        ballonsArray.append(balloon)
        addChild(balloon)
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        ballonsArray.map { $0.xScale = 0.2 }
    }
}

Hope this helps.

2 Comments

Could it be because your Point 1 is totally bogus?
@matt: The OP reported a warning and an error from the compiler: they are added as comments in the block of code of the question. I tried to answer both. I have read lots of your answers matt and I totally respect your knowledge about Swift, but now I don't understand where I am wrong.

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.