2017-01-05 9 views
0

私の最初のGameViewControllerに初期のViewControllerのための強力なデリゲートを使用すると、GameDelegateのデリゲートプロパティを持っています。私はAppDelegateでこのプロパティを設定しています:AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
    // Override point for customization after application launch. 

    //Set initial view controller 
    window = UIWindow(frame: UIScreen.main.bounds) 
    if let window = window { 
     let gameTracker = GameTracker() 
     let gameViewController = GameViewController() 
     gameViewController.delegate = gameTracker 
     window.rootViewController = gameViewController 
     window.makeKeyAndVisible() 
    } 
    return true 
} 

これだけ作品私のデリゲートが強いため:デリゲートは、後にはnilとなりますので、弱いデリゲートを使用して

class GameViewController: UIViewController{ 

     var delegate: GameDelegate? 

     var gameScore: GameScore { 
      return (delegate!.gameScore) 
     } 

     override func viewDidLoad() { 
      super.viewDidLoad() 
     } 
    } 

は、AppがクラッシュしますGameViewControllerが提示される。

私の質問は次のとおりです。このアプローチは安全です、とされていない場合、それがどのように行われるべき?私はデリゲートについて読んだことがあり、保持サイクルを防ぐために弱いvarとして保持することをお勧めします。私はストーリーボードを使用していません。

答えて

2

問題は、関数ではなく、クラスレベル変数としてgameTrackerを宣言しているということです。機能が終了するとすぐにAppDelegateの参照が解放され、GameViewControllerの参照のみが残されます。

これを解決する方法は、お使いのAppDelegateにクラスレベルの変数としてgameTrackerを宣言することです:

var gameTracker: GameTracker? 

あなたがた場合にのみ、あなたのif条件、それをインスタンス化したいので、あなたは、オプションとしてそれを宣言する必要があります満たされる:

if let window = window { 
    self.gameTracker = GameTracker() 
    let gameViewController = GameViewController() 
    gameViewController.delegate = self.gameTracker 
    window.rootViewController = gameViewController 
    window.makeKeyAndVisible() 
} 

あなたがこれを行う場合、あなたはGameViewControllerであなたのdelegateweakとして宣言することができるようになります。

+0

私は本当にARCからの2つの参照を数えたので、これは意味があります。ありがとうございました! – Hapeki

1

安全なアプローチが弱いデリゲートを使用しています。あなたがnilを扱うなら、それは問題ではないはずです。

weak var delegate: GameDelegate? 

var gameScore: GameScore? { 
    return delegate?.gameScore 
} 

'gameScore'が変更された場合、「代理人」を呼び出すつもりはありますか? 'gameScore'を保存し、 'delegate'を返す場合は、プロパティオブザーバを使用する必要があります。

var gameScore: GameScore { 
    didSet { 
     delegate?.gameScore 
    } 
} 
+0

はい、これは私が代わりに弱いものの強いデリゲートを使用しています正確な理由です。計算されたプロパティはデリゲートを呼び出す必要があります。 – Hapeki