質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2161閲覧

tableView上のUIViewを開放したい

midomurasaki

総合スコア46

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/11/22 00:38

Xcode9, swift4でiOSアプリを開発しています。
構成としては、

  • FirstViewController(遷移元)
  • SecondViewController(遷移先, tableView)

があり、SecondViewControllertableViewcellをStoryboardで作成しています。
cell上には自分で作成したTestViewを乗せ、Tagを設定しcell生成時に取得しています。

このTestViewもStoryboardとXibで作成し、Timerを持っています。

swift

1 2import UIKit 3 4class TestView: UIView { 5 6 var timer: Timer? 7 let timerInterval: TimeInterval = 60 8 9 override init(frame: CGRect) { 10 super.init(frame: frame) 11 loadXib("TestView") 12 } 13 14 required init(coder aDecoder: NSCoder) { 15 super.init(coder: aDecoder)! 16 loadXib("TestView") 17 } 18 19 fileprivate func loadXib(_ nibName: String) { 20 let bundle = Bundle(for: type(of: self)) 21 let nib = UINib(nibName: nibName, bundle: bundle) 22 let view = nib.instantiate(withOwner: self, options: nil).first as! UIView 23 addSubview(view) 24 25 view.translatesAutoresizingMaskIntoConstraints = false 26 let bindings = ["view": view] 27 addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:nil, views: bindings)) 28 addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", options:NSLayoutFormatOptions(rawValue: 0), metrics:nil, views: bindings)) 29 } 30 31 override func didAddSubview(_ subview: UIView) { 32 super.didAddSubview(subview) 33 setTimer() 34 } 35 36 override func removeFromSuperview() { 37 // 呼ばれない 38 timer?.invalidate() 39 } 40 41 func setTimer() { 42 timer = Timer.scheduledTimer(timeInterval: timerInterval, target: self, selector: #selector(self.update), userInfo: nil, repeats: true) 43 timer?.fire() 44 } 45 46 @objc func update(tm: Timer) { 47 print("hello") 48 } 49 50} 51

cellの生成部分のコードは下記です。

swift

1extension SecondViewController: UITableViewDelegate, UITableViewDataSource { 2 // 省略 3 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 4 var cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "testCell", for: indexPath) 5 if let testView: TestView = cell.viewWithTag(1) as? TestView { 6 print("add TestView") 7 } 8 return cell 9 } 10 // 省略 11}

###発生している問題
cellも正しく追加され、60秒毎のtimerによる処理は問題無く行われるのですが、SecondViewControllerからFirstViewControllerへ戻った際にremoveFromSuperview()が呼ばれず、Timerが動き続けてしまいます。
cell上のviewを開放するにはどうしたらよいか、アドバイスいただけますでしょうか。

以上、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

didAddSubview(_:)の動作を勘違いしています。
この関数は、自分にsubviewが追加されたときに呼ばれる関数です。(セル生成時に複数回呼ばれるのでタイマーも複数生成されてしまっている → 止めているのは最後のタイマーだけ)

add/removeされたときに処理を行うのであれば、

swift

1override func willMove(toSuperview newSuperview: UIView?) { 2 if newSuperview != nil { 3 //add時の処理 4 } else { 5 //remove時の処理 6 } 7}

処理内容によっては、init/deinitとか、didMoveToSuperview/removeFromSuperviewの方が良いかも知れません。

投稿2017/11/22 01:30

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

midomurasaki

2017/11/22 02:16 編集

ご回答ありがとうございます。 breakpointを設定してもremoveFromSuperview()もご回答いただいたelse {...}の部分も呼ばれず、どこかで循環参照が起こっているのでは?と調べた結果、tableViewのcell生成用配列を取得するFirebaseのobserverが正しく開放されていないことが判明し、修正したところご回答いただきましたコードで正しく動作するようになりました。
fuzzball

2017/11/22 02:26

「タイマーが止まってないからremoveFromSuperviewが呼ばれていない」と判断したのかと思ったら、本当に呼ばれてなかったんですね。まぁ解決して良かったです。 ちなみに、もう関係無い話だとは思いますが、overrideしたremoveFromSuperviewの中で super.removeFromSuperview() が呼ばれてないです。
midomurasaki

2017/11/22 02:32

結局根本の原因は別のところにありましたがdidAddSubview(_:)の勘違いもあり、質問しなければまたハマっていたと思うので質問して良かったです。 superの抜けについてもご指摘いただきありがとうございます。大変助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問