2017-09-08 30 views
0

既存のアプリでUIDocumentBrowserViewControllerを実装しています。このvcは、iOS 11ではルートビューコントローラであり、ファイルをタップするとドキュメントが作成され、ビューコントローラがインスタンス化され、UINavigationControllerの内部に表示されます。ファイルが表示され、適切なドキュメントが開き、vcが表示され、期待どおりに動作するという点で、すべて動作します。 doc/vcを終了する方法を提供するために、ナビゲーションバーに左ボタンを追加する必要がありました。uinavigationcontrollerを無効にしてView Controllerのメモリを解放しないのはなぜですか?

「完了」ボタンをタップすると、ビューコントローラが閉じてドキュメントブラウザに戻ります。そのすべてが良いです。

問題は、ビューコントローラのメモリが解放されていないことです(ドキュメントメモリなどのドミノ効果が解放されない)。物事のiOS 10側では、最初のVCとしてUINavigationControllerに埋め込まれたUICollectionViewControllerが、iOS 10 & 11のすべてのメモリリリースではdocとディスプレイvcの同じコードが埋め込まれています。私はHow to correctly dismiss a UINavigationController that's presented as a modal?と関連記事を学び、数多くの選択肢を試してみて、私が見逃しているものは見ていません。インストゥルメントはメモリリークを表示していませんが、View Controllerを終了した後にメモリ内のドキュメントオブジェクトが表示されます。ログは、vcのviewWillDisappearが適切な時刻に呼び出されていることを示しています。

なぜvcメモリがリリースされていないのかを理解しています(deinit()は呼び出されません)。

ありがとうございます。

@available(iOS 11.0, *) 
class DocumentBrowserViewController: UIDocumentBrowserViewController, UIDocumentBrowserViewControllerDelegate { 

override func viewDidLoad() { 
    super.viewDidLoad() 

    delegate = self 

    allowsDocumentCreation = true 
    allowsPickingMultipleItems = false 
} 

// MARK: Document Presentation 

func returnToDocumentBrowser(sender: UIBarButtonItem) { 
    print("returnToDocumentBrowser") 
    if let controller = self.presentedViewController as? UINavigationController { 
     controller.dismiss(animated: true, completion: nil) 
    } 
} 

func presentDocument(at documentURL: URL) { 
    print("present document") 

    let doc = MyDocument(fileURL: documentURL) 
    doc.open(completionHandler: { (success) in 
     if (success) { 
      print("open succeeded") 
      DispatchQueue.main.async { 
       let myController = self.storyboard!.instantiateViewController(withIdentifier: "my controller") as! MyViewController 
       myController.navigationItem.setLeftBarButton(UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(self.returnToDocumentBrowser(sender:))), animated: false) 
       myController.doc = doc 

       let navigationController = UINavigationController(rootViewController: myController) 
       self.present(navigationController, animated: true, completion: nil) 
      } 
     } else { 
      print("open failed") 
     } 
    }) 
} 
} 
+0

閉鎖の実装でサイクルを保持している可能性があります。 '(weak self)'を '(success)in'の前に使って、self.presentをオプションで使用してみてください。このように 'self?.present(navigationController、animated:true、completion:nil)'私に知らせてください –

+0

提案していただきありがとうございます。それは行動を変えなかった。私はまた、[無所属の自己を]自分自身にしようとしました/彼らが必要であるかどうかわからなくても、まっすぐに保つことはできません。それは精神的なブロックです。どちらからも影響はありません。 – JKaz

+0

どこに 'delegate'宣言がありますか?弱いです? –

答えて

0

ナビゲーションスタックがこの中心にあるようです。 iOS 10バージョンでは、コレクションビューコントローラはルートビューコントローラであり、ストーリーボード経由でナビゲーションコントローラに組み込まれています。

iOS 11バージョンでは、ドキュメントブラウザビューコントローラはルートビューコントローラであり、ナビゲーションコントローラに組み込むことはできません。元のコードで提示したとき、私のドキュメントビューコントローラは、ナビゲーションスタックのルートビューコントローラとなり、たとえばポップすることはできません。

ナビゲーションコントローラに、以前の動作を可能な限り模倣し、コードの変更を最小限に抑えるために、別のルートビューコントローラが必要なのではないかと考えました。

だから私は

  let navigationController = UINavigationController(rootViewController: myController) 
      self.present(navigationController, animated: true, completion: nil) 

    let dummyVC = UIViewController() 
        let navigationController = UINavigationController(rootViewController: dummyVC) 
        from.present(navigationController, animated: true, completion: nil) 
        dummyVC.navigationController?.pushViewController(myController, animated: true) 

このナビゲーションコントローラの設定は、私は戻るボタンを追加する必要はありませんでした、そしてそれは、ビューコントローラをポップに扱わ意味、戻るボタンを追加、変更自動的に。その結果、私はnavコントローラを却下する必要がありました。これは、アプリケーションのルートVCではなかったからです。

最後に、デリゲートを弱く宣言する必要があるというコメントは、アップルがやっていることです。私はそれをそのまま使っています。私は物事に何が影響しているのか分かりません。

関連する問題