weak reference surprised to nil

i surprised to find nil when i set weak prifix, the code show below:

classA { classB {

var b: classB var col: CGFloat

var col: CGFlaot func run(col: CGFloat){ }

} }

classB`s var or func need to use classA`s var col, so use function code in classA like below:

dispatchQueue_main_async {[ weak self ] in or dispatchQueue_main_async{

if let strongself = self{ self.b = self.getB( ) }

self?.b.col = strongself.col } } func getB( ) -> classB{

let b = classB( )

b.col = { [weak self ] in self?.col } }

i cannot convey classA`s var col to property and function of classB.

thanks for your appriciation.

Replies

Please explain:


— Why use "weak"?


Code like this should be OK:


DispatchQueue.main.async {
     self.b.col = self.col // or just: b.col = col
     self.b.run(self.col)  // or just: b.run(col)
}

if not [weak self ] in classA, i should use "weak var a: classA? " in the classB to convey var col of classA to var col and func of classB.

so use weak broke out referencr cycle.

your method i have tryed but also get nil in classB, use "guard" to test "var col" and func run( ) in classB appearing nil. func run() in classB called by GKStrategy object of classA.

virtually, classA is my GameScene swift and classB is my Board with GKGameModel protocol, i use func run( ) to get moves for func gameModelUpdeatesFor( player: GKGameModelPlayer ) -> [GKGameModelUpdate ]? { return run( ) }, unfortunately, guard appear "var col" nil.

Yes, but you didn't show any reference cycles. An object of class A has a reference to an object of class B, but there is no reference from B to A.


Your closures (DispatchQueue.main.async { … }) do not create any reference cycles. That's because there are no references from an A or a B to the closures.


Do you have an actual code fragment that shows a reference cycle?

func gameModelUpdates(for player: GKGameModelPlayer) -> [GKGameModelUpdate]? {

guard player.playerId == 0 || isRequest else {

return nil

}

guard let moves = self.run( ) else{fatalError("no moves !")}. ( appear "fatalError: col nil ")

return moves as [GKGameModelUpdate]

}


func run( col: CGFloat?){

guard let col = col else { fatalError("col nil")

}

why var col and func run( ) from classB is nil, why can not convey var col in classA to var col and func run ( ) from classB

You have this:


     guard let moves = self.run( ) else ...


and you have this:


     func run( col: CGFloat?) ...



These are not the same "run" function. The first one has no parameters — run( ) — but the second one has one parameter — run(col:). Now, if you really have this:


func run( col: CGFloat? = nil){ // <- default parameter value
      guard let col = col else { fatalError("col nil")
}


then self.run( ) really means self.run(col: nil), and that will crash with a fatal error "col nil".

yes , the different run( ) is the same function , and now the fatal error "col nil" disappears automatically when implement, but i do not know why disappears.