2016-12-24 12 views
-2

私はDownloaderDelegateプロトコルを使用してDownloaderHandlerと通信するviewControllerを持っています。私のメソッドが呼び出されないのはなぜですか?

私のプロトコルは次のように定義されます、ラインAAを取得します。私はViewControllerを

class ViewController: UIViewController { 
weak var downloadHandler : DownloaderHandler?  

override func viewDidLoad() { 
    super.viewDidLoad() 
    downloadHandler = DownloaderHandler() 
    downloadHandler?.delegate = self 
    changeBackground() 

} 

func changeBackground(){ 
     let googleURL = URL(fileURLWithPath: "https://www.google.com/doodle4google/images/splashes/featured.png") 
     print(googleURL) 
     downloadHandler?.downloadData(url:googleURL) // Line BB 
    } 
} 

extension ViewController : DownloaderDelegate{ 
    func didReceive(data: Data) { 
     let image = UIImage(data: data) 
     let imageView = UIImageView(image: image!) 
     view.insertSubview(imageView, at: 0) 
    } 
} 

を持っていると私のように委任クラスを持っている

protocol DownloaderDelegate : class { 

    func didReceive(data:Data) 
} 

:ブレークポイントを使用して

class DownloaderHandler : NSObject, URLSessionDelegate{ 
    weak var delegate :DownloaderDelegate? 
    var downloadsSession: URLSession = { 
     let configuration = URLSessionConfiguration.default 
     let session = URLSession(configuration: configuration) 
     return session // Line AA 
    }() 

    func downloadData(url: URL){ // Line CC 
     downloadsSession.dataTask(with: url){ data, response, error in 
      print("error is \(error), data is \(data) and response is \(response)") // Line DD 

      if let badError = error { 
       print(" the url didn't succeeed error is \(badError.localizedDescription)") 
      } 
      else if let someResponse = response as? HTTPURLResponse { 
       if someResponse.statusCode == 200{ 
        self.delegate?.didReceive(data: data!) 
       } 
      } 

     } 

    } 
} 

ロードされる。ラインBBコール。ラインCCは決して呼び出されません。どうして?何が間違っているのですか?

答えて

4

あなたが宣言した:

weak var downloadHandler : DownloaderHandler?  

は、次に、あなたが言う:

downloadHandler = DownloaderHandler() 

downloadHandlerweak参照され、そして他には何もこのDownloaderHandlerインスタンスを保持していないので、それはそれの後に煙の中に消えます創造された。ログにはログが作成されていることが示されていますが、ログオンする場合はdeinitと表示されます。 downloadHandler?.downloadData(url:googleURL)と言うときには、downloadHandlerの参照はnilとなり、何も起こりません。その時点であなたは誰とも話していません。

[委任参照が弱いという精神的なルールに従っていると思われます。しかし、そのルールは、デリゲートが独立した存在であるため、リファラーによって「所有」されるべきではないという前提に基づいています。しかし、このオブジェクトは独立した存在はありません。より多くのデコレータオブジェクト(私はヘルパーと呼ぶもの)です。したがって、基準を強くする必要があります。バックリファレンスはまだ弱いので、循環保持サイクルは得られません。]

+0

hah私はこの「weak var delegate:DownloaderDelegate? 'それで。 – Honey

+0

私はどこにあなたの考えに間違っていたかを推測しようとしている段落を追加しました::) – matt

+0

私は '弱い 'を削除しました。今私はラインCCをヒットしましたが、私は決して完了DDの中の何も実行されません。完成ハンドラに何か問題はありますか? – Honey

1

View ControllerのdownloadHandlerプロパティから「weak」修飾子を削除します。

downloadHandlerオブジェクトへの唯一の参照であるため、viewDidLoadメソッドの実行が終了するとすぐにメモリから削除されます。

小さなテストを行うことができます。ブレークポイントをBB行に追加し、downloadHandlerに値があるかどうかを確認します。私はそれが弱い財産であるので、それは "なし"と思われる。

関連する問題