UIActivityViewControllerを使うと発生するメモリリークの解消方法を教えてください
swiftでアプリを開発しています。
UIActivityViewControllerを使ってアクティビティダイアログを表示した際にメモリリークしています。
リークを解消させる方法の見当がつかず困っています。解決方法についてご教示ください。
コードは最後に載せておきます。(一部書き換えています。)
処理内容は、出力したCSVファイルをアクティビティダイアログに表示されたAirDropまたはメーラーで送信する、というものです。
instrumentsで確認した際のssを添付します。iphone(ios8.4)と、ipadmini(ios9.3.4)で実行しました。それぞれダイアログを表示させる画面へ遷移し5回ダイアログを開閉しました。
↑iphoneでは「_UIAlertControllerCommmonInit」でNSMutableArrayがリークしているようです。このssでは2つのリークですが、開閉の回数分リークしている時もあります。
↓ipadのssはスタックトレースの内容が異なる3枚を載せておきます。(他のは、IsImage、IsContactの部分のみがIsPDFのような感じで異なっています。)
ipadでは「CSStringCopyCFString」でNSCFStringがドカドカとリークしています。さらに開閉する毎にヒープが高くなっている(閉じても何か残っている?)点も気になります。こちらについても原因や回避策があればお教えください。よろしくお願いいたします。
/// ボタン押下時処理(CSVファイル作成+転送)
func tapButton() {
//CSVファイルを出力
let strFullPath: String = outputCSVFile("sample.csv")
print("csvpath:" + strFullPath)
//(出力成功)アクティビティダイアログ表示
if strFullPath != "" {
_ad = MyAd() //広告をロード
let body: String = NSLocalizedString("MSG_SEND", comment: "body文言")
let file = NSURL(fileURLWithPath: strFullPath)
let handler: (Bool -> Void) = { [unowned self] (completed) in
if completed == true {
self._ad?.show(self)
print("CSV送信完了!")
}
}
dispDialog(self, items: [body, file], btn: btnAction, arrow: .Up, handler: handler)
//(出力失敗)エラーメッセージ表示
} else {
dispErrMsg(self, strMsg: NSLocalizedString("MSG_FILE_ERR", comment: "エラー発生"))
}
}
/// アクティビティダイアログを表示
class func dispDialog(vc: UIViewController, items: [AnyObject], btn: UIBarButtonItem, arrow: UIPopoverArrowDirection = .Unknown, handler: (Bool -> Void)! = nil) {
let dialog = UIActivityViewController(activityItems: items, applicationActivities: nil)
//使用しないアクティビティタイプ
let excluded = [
UIActivityTypeCopyToPasteboard,
UIActivityTypeMessage,
]
dialog.excludedActivityTypes = excluded
//完了後の処理をセット
if handler != nil {
dialog.completionWithItemsHandler = { (activityType: String?, completed: Bool, returnedItems: [AnyObject]?, error: NSError?) in
print("activityType: \(activityType)")
handler(completed)
return
}
}
//For iPad And Univarsal Device
if let popCtrl = dialog.popoverPresentationController {
popCtrl.sourceView = vc.view
popCtrl.permittedArrowDirections = arrow
popCtrl.barButtonItem = btn
}
vc.presentViewController(dialog, animated: true, completion: nil)
}