忍者ブログ
  • 2024.10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 2024.12
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

【2024/11/22 20:11 】 |
iOSで通知タイマーを管理する
アプリ内でNSTimerを発行したいときがある。

◯記述場所
NSTimerは、アプリが起動している間だけ生きていれば良かったので、Model層では扱う必要が無い。
だからViewControllerで完結させるように記述した。


◯破棄
さて、NSTimerはキャンセルすることもできるようにしたい。
ということは、作成したNSTimerのインスタンスを保持しておく必要がある。
NSTimerインスタンスの生成・破棄及び参照保持と削除のタイミングは、

・作成ボタン押下
インスタンス化、参照保持

・キャンセルボタン押下
無効化、参照削除

・タイマー発動
参照削除(←忘れがちだがここでもちゃんと削除しておく。そうでないとvalidでないNSTimerインスタンスの参照がずっと残ることになる)

ということになる。

さてインスタンスの保持の方法だが、
[NSTimer]
Array<NStimer>
Dictionary
NSMutableSet

といろいろあるが、試してみて一番便利なのは

NSMutableSet

だった。
なぜなら、削除したいインスタンスを直接
set.removeObject(timer)
という形で指定できるからである。
それ以外の型だと、削除していいインスタンスかどうかの判定のロジックを書かなければならなくなる。


◯別のViewControllerから生成・削除させる

キャンセルは実は別の画面から行われることもある、という場合。
あるViewControllerから別のViewControllerにどうやって情報を伝達するか。

NotificationCenterを使う。

・通知を発信する側

var notification = NSNotification(name: "RemoveInAppNotification", object: self, userInfo: ["data": declareData!])
NSNotificationCenter.defaultCenter().postNotification(notification)

なおuserInfoは必ず Dictionary? 型でないといけない

・通知を受け取る側

NSNotificationCenter.defaultCenter().addObserver(self, selector: "removeInAppNotifications:", name: "RemoveInAppNotification", object: nil)

func removeInAppNotifications(notification: NSNotification) {
//notification.userInfo などを使って処理
}

となる。
nameはもちろん揃っている必要がある。
通知を受け取る側は、addObserver()やremoveObserver()を正しく書いておく必要がある。
画面に出入りしたときにadd/removeObserverしたいところだが、この場合はいけない。
「別の画面から呼び出されたとき」に通知を受け取りたいからである。
もちろん、該当のViewControllerが常にメモリ上に存在している保証が必要だ(そんなことできるのか?)


以上まとめるとコードは以下のようになる


class MyViewController{

//宣言タイマー
var reminderTimers: NSMutableSet = NSMutableSet()

override func viewDidLoad() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "removeInAppNotifications:", name: "RemoveInAppNotification", object: nil)
}

func makeInAppNotification(data: DeclareData, delayedSec: NSTimeInterval, message: String){
var userInfo = ["data": data, "message": message]
var t = NSTimer.scheduledTimerWithTimeInterval(delayedSec, target: self, selector: "showInAppNotification:", userInfo: userInfo, repeats: false)
reminderTimers.addObject(t)
}

//指定した宣言のタイマーを削除
func removeInAppNotifications(notification: NSNotification) {
var targetDeclareId = (notification.userInfo?["data"] as DeclareData).declareId

for obj in reminderTimers {
var timer = obj as NSTimer
if timer.valid {
var dic = timer.userInfo as NSDictionary
var timerData = dic["data"] as DeclareData
if timerData.declareId == targetDeclareId {
timer.invalidate()
reminderTimers.removeObject(timer)
}
}
else{
reminderTimers.removeObject(timer)
}
}
}

//NSTimerから呼び出されるメソッド
func showInAppNotification(timer: NSTimer){
var dic = timer.userInfo as NSDictionary
//var data = dic["data"] as DeclareData
var message = dic["message"] as String

UtilAlertView("", message, "OK")

reminderTimers.removeObject(timer)
}

}

class OtherViewController{
@IBAction func cancelButtonPressed(sender: UIButton) {
var notification = NSNotification(name: "RemoveInAppNotification", object: self, userInfo: ["data": declareData!])
NSNotificationCenter.defaultCenter().postNotification(notification)
}
}







PR
【2015/07/12 18:54 】 | iPhone | 有り難いご意見(0)
<<cocos2d-x(v3.7)の新しいプロジェクトを作成する | ホーム | cocos2d-xのラベルはグローバルZが実質使えない>>
有り難いご意見
貴重なご意見の投稿














<<前ページ | ホーム | 次ページ>>