Non-strong references not working in playground

2019-02-19 01:37发布

问题:

I was reading the swift programming guide, and in the initializers chapters I came across this code:

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    deinit { println("\(name) is being deinitialized") }
} 

class CreditCard {
    let number: Int
    unowned let customer: Customer
    init(number: Int, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { println("Card #\(number) is being deinitialized") }
}

So I tried to try the code myself and make some changes to see what happens (makes me understand more )

So I opened the playground and started typing, after that I noticed that the weak keyword and the unowned keyword aren't recognized by the playground. This could only mean that playground only support strong reference variables.

So why does playground only support strong reference, and what could you do to prevent a strong reference cycle in playground?

回答1:

The playground is only a playground. It isn't a very exact representative of real life. So you should not be surprised if it treated memory management differently from real life. (Another example: the top level of a playground is clearly not like the top level of a real Swift file, since you can put things there that are not declarations and they work.)

You can use a playground for developing algorithms interactively, but only real life (i.e. a compilable executable .swift file) is real life.

For example, I put this in the App Delegate of an actual iOS app:

import UIKit

class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    deinit { println("\(name) is being deinitialized") }
}

class CreditCard {
    let number: Int
    unowned let customer: Customer
    init(number: Int, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { println("Card #\(number) is being deinitialized") }
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        // Override point for customization after application launch.
        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()

        var cust = Customer(name:"Matt")
        var cc = CreditCard(number:1234, customer:cust)
        cust.card = cc

        return true
    }
}

I saw the two println messages, proving that there was no retain cycle. If I deleted the unowned keyword and ran again, I didn't see the two println messages, proving that there was a retain cycle. Thus we know that unowned does what it is advertised to do. That's all we need to know. What works or doesn't work in a playground isn't terribly important.



回答2:

You can also create a console app (New Project > macOS > Command Line Tool) This way, you don't need to have simulator running when you run your code.



标签: swift xcode6