Retaining repeating NSTimer for later access?

前端 未结 3 1461
隐瞒了意图╮
隐瞒了意图╮ 2021-01-28 04:53

I am creating an NSTimer in the createTimer method that I want to refer back to in the later cancelTimer method. To facilitate this I am taking ownersh

3条回答
  •  一生所求
    2021-01-28 05:21

    Don't retain a scheduled NSTimer if you've set its target to self Don't set self as the target of a repeating timer unless you are absolutely sure to know all the consequences

    (...otherwise the runtime drowns a kitten in leaked timers, targets and userInfos — or so goes the saying.)

    Please read and re-read "Overview" in the NSTimer Class Reference and pay special attention to the last paragraph.

    In a nutshell:

    1. If you schedule an NSTimer, it becomes associated to the current run-loop which retains it.
    2. Furthermore, the timer retains its target.
    3. NSTimer instances are not reusable: "Once invalidated, timer objects cannot be reused".

    So there is no point in retaining a scheduled timer in the first place.

    If you need to hang on to it (e.g. in order to cancel it) use a non-owning (aka weak) reference to it.

    Update:
    For a thorough explanation, see my answer to your other question (it now has graphs — albeit as links only — and stuff).

    Please consider the rest of this post (as well as many of my comments) as obsolete.


    Your property becomes

    @property (nonatomic, assign) NSTimer *walkTimer;
    

    BTW:

    -(void)cancelTimer {
        [self setWalkTimer:nil]; // great, now [self walkTimer] returns nil so
        [[self walkTimer] invalidate]; // here, you are calling [nil invalidate]
    }
    

    And since messaging nil is absolutely fine in Objective C, your crash miraculously vanishes...while your timer will happily continue to fire.

    Edit

    I've forgot to mention:
    A timer wants a selector that takes one argument, which will be the timer that fired... Or is that just a typo?

提交回复
热议问题