• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag
 

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSTimer +timerWithTimeInterval:
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSTimer +timerWithTimeInterval:


  • Subject: Re: NSTimer +timerWithTimeInterval:
  • From: Chris Walters via Cocoa-dev <email@hidden>
  • Date: Thu, 30 Apr 2020 00:03:26 +0100

I’m not suggesting you do this as any kind of real solution I just wanted to
see if it would work, but I was able to ‘hack’ the immutable timer interval,
perhaps something like this can help you track down what is happening.  I found
a couple of structs in GitHub for CF source and wondered if it was possible to
poke at the values.  As I said please don’t think I’m suggesting this as a
fix...

// found on Github
typedef struct __MYCFRuntimeBase {
    uintptr_t _cfisa;
    uint8_t _cfinfo[4];
#if __LP64__
    uint32_t _rc;
#endif
} MYCFRuntimeBase;

typedef struct __CFRunLoopTimer {
    MYCFRuntimeBase _base;
    uint16_t _bits;
    pthread_mutex_t _lock;
    CFRunLoopRef _runLoop;
    CFMutableSetRef _rlModes;
    CFAbsoluteTime _nextFireDate;
    CFTimeInterval _interval;           /* immutable */
    CFTimeInterval _tolerance;          /* mutable */
    uint64_t _fireTSR;                  /* TSR units */
    CFIndex _order;                     /* immutable */
    CFRunLoopTimerCallBack _callout;    /* immutable */
    CFRunLoopTimerContext _context;     /* immutable, except invalidation */
} MYCFRunloopTimer;

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0 // should be 1/sec
            target:self selector:@selector(newData:) userInfo:nil  repeats:YES];
    CFTimeInterval newTimerIntervalFromCF = CFRunLoopTimerGetInterval((__bridge
CFRunLoopTimerRef) newTimer);

    NSLog(@"CF Timer Interval: %5.2f", newTimerIntervalFromCF);
    NSLog(@"Timer Interval as property: %5.2f", [newTimer timeInterval]);

    // make a hacked version
    MYCFRunloopTimer *myTimer = (__bridge MYCFRunloopTimer *)newTimer;
    NSLog(@"Hacked TimerInterval before hacking it: %5.2f", myTimer->_interval);
    myTimer->_interval = 5.0f;
    NSLog(@"Hacked TimerInterval after hacking it: %5.2f", myTimer->_interval);

    // See if the hacked value was set into the CF struct
    newTimerIntervalFromCF = CFRunLoopTimerGetInterval((__bridge
CFRunLoopTimerRef) newTimer);

    NSLog(@"After hack CF Timer Interval: %5.2f", newTimerIntervalFromCF);
    NSLog(@"After hack timer Interval as property: %5.2f", [newTimer
timeInterval]);

    [[NSRunLoop mainRunLoop] addTimer:newTimer forMode:NSRunLoopCommonModes];
}

- (void) newData:(NSTimer *)timer {
    NSLog(@"timer is %@", timer);
}

2020-04-30 00:00:19.372 TestTimer[8777:362408] CF Timer Interval:  1.00
2020-04-30 00:00:19.372 TestTimer[8777:362408] Timer Interval as property:  1.00
2020-04-30 00:00:19.372 TestTimer[8777:362408] Hacked TimerInterval before
hacking it:  1.00
2020-04-30 00:00:19.372 TestTimer[8777:362408] Hacked TimerInterval after
hacking it:  5.00
2020-04-30 00:00:19.372 TestTimer[8777:362408] After hack CF Timer Interval:
5.00
2020-04-30 00:00:19.372 TestTimer[8777:362408] After hack timer Interval as
property:  5.00
2020-04-30 00:00:20.372 TestTimer[8777:362408] timer is <__NSCFTimer:
0x7fd1fa45f550>
2020-04-30 00:00:25.373 TestTimer[8777:362408] timer is <__NSCFTimer:
0x7fd1fa45f550>
2020-04-30 00:00:30.372 TestTimer[8777:362408] timer is <__NSCFTimer:
0x7fd1fa45f550>
2020-04-30 00:00:35.372 TestTimer[8777:362408] timer is <__NSCFTimer:
0x7fd1fa45f550>
2020-04-30 00:00:40.371 TestTimer[8777:362408] timer is <__NSCFTimer:
0x7fd1fa45f550>


> On 29 Apr 2020, at 23:51, Ken Thomases via Cocoa-dev
> <email@hidden> wrote:
>
> Does this happen only when launched from Xcode, or also when launched
> normally?  Does this happen with a different user account?  Does it happen
> when run on another Mac?
>
> -Ken
>
>> On Apr 29, 2020, at 4:35 PM, Carl Hoefs via Cocoa-dev
>> <email@hidden> wrote:
>>
>> There are no extensions or categories in the project.
>> I changed the -newData: method name to -arrivalOfNewData:.
>> I changed the newTimer variable name to theTimer.
>> I rebooted the machine.
>>
>> No joy.
>>
>> I realize this is no longer a Cocoa problem, but what - even theoretically -
>> could cause this?
>> As shown in the debugger, the timer gets created with the wrong time
>> interval value, by a consistent factor of 20.
>>
>> -Carl
>>
>>
>>> On Apr 29, 2020, at 2:24 PM, Andy Lee <email@hidden> wrote:
>>>
>>> I did the same just now in a macOS project.  Copied your code and added a
>>> newData: method.  This is with Xcode 11.2.1 on Mojave, 10.4.6.  Works fine
>>> for me.  Weird!
>>>
>>> @implementation AppDelegate
>>>
>>> - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
>>>   NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0  // should be 1/sec
>>>                                               target:self
>>>                                             selector:@selector(newData:)
>>>                                             userInfo:nil
>>>                                              repeats:YES];
>>>   [[NSRunLoop mainRunLoop] addTimer:newTimer
>>>                             forMode:NSRunLoopCommonModes];
>>> }
>>>
>>> - (void)newData:(NSTimer *)timer {
>>>   NSLog(@"timer is %@", timer);
>>> }
>>>
>>> @end
>>>
>>> 2020-04-29 17:20:45.331469-0400 NSTimerQuestion[21676:3985041] Metal API
>>> Validation Enabled
>>> 2020-04-29 17:20:46.413190-0400 NSTimerQuestion[21676:3985041] timer is
>>> <__NSCFTimer: 0x60000370eb80>
>>> 2020-04-29 17:20:47.412968-0400 NSTimerQuestion[21676:3985041] timer is
>>> <__NSCFTimer: 0x60000370eb80>
>>> 2020-04-29 17:20:48.413525-0400 NSTimerQuestion[21676:3985041] timer is
>>> <__NSCFTimer: 0x60000370eb80>
>>> 2020-04-29 17:20:49.413373-0400 NSTimerQuestion[21676:3985041] timer is
>>> <__NSCFTimer: 0x60000370eb80>
>>> 2020-04-29 17:20:50.412610-0400 NSTimerQuestion[21676:3985041] timer is
>>> <__NSCFTimer: 0x60000370eb80>
>>> ...
>>>
>>> --Andy
>>>
>>> On Apr 29, 2020, at 5:15 PM, Alex Zavatone via Cocoa-dev
>>> <email@hidden <mailto:email@hidden>> wrote:
>>>>
>>>> I used your code in an iOS project and it works as expected.
>>>>
>>>> 2020-04-29 16:14:02.254107-0500 Timer[83275:13268128] Wed Apr 29 16:14:02
>>>> 2020
>>>> 2020-04-29 16:14:03.254048-0500 Timer[83275:13268128] Wed Apr 29 16:14:03
>>>> 2020
>>>> 2020-04-29 16:14:04.253957-0500 Timer[83275:13268128] Wed Apr 29 16:14:04
>>>> 2020
>>>> 2020-04-29 16:14:05.254170-0500 Timer[83275:13268128] Wed Apr 29 16:14:05
>>>> 2020
>>>> 2020-04-29 16:14:06.254490-0500 Timer[83275:13268128] Wed Apr 29 16:14:06
>>>> 2020
>>>> 2020-04-29 16:14:07.254570-0500 Timer[83275:13268128] Wed Apr 29 16:14:07
>>>> 2020
>>>> 2020-04-29 16:14:08.254651-0500 Timer[83275:13268128] Wed Apr 29 16:14:08
>>>> 2020
>>>> 2020-04-29 16:14:09.253715-0500 Timer[83275:13268128] Wed Apr 29 16:14:09
>>>> 2020
>>>> 2020-04-29 16:14:10.254741-0500 Timer[83275:13268128] Wed Apr 29 16:14:10
>>>> 2020
>>>>
>>>> I’ll mail you the project offlist.
>>>>
>>>>
>>>>
>>>>> On Apr 29, 2020, at 4:07 PM, Carl Hoefs via Cocoa-dev
>>>>> <email@hidden <mailto:email@hidden>> wrote:
>>>>>
>>>>> On Apr 29, 2020, at 1:53 PM, Carl Hoefs via Cocoa-dev
>>>>> <email@hidden <mailto:email@hidden>> wrote:
>>>>>>
>>>>>> On Apr 29, 2020, at 1:43 PM, Steve Mills via Cocoa-dev
>>>>>> <email@hidden <mailto:email@hidden>
>>>>>> <mailto:email@hidden <mailto:email@hidden>>>
>>>>>> wrote:
>>>>>>>
>>>>>>> On Apr 29, 2020, at 15:36:23, Carl Hoefs via Cocoa-dev
>>>>>>> <email@hidden <mailto:email@hidden>> wrote:
>>>>>>>>
>>>>>>>> When I issue NSTimer's +timerWithTimeInterval::::: method, I'm getting
>>>>>>>> unexpected timer firing times (20X faster than expected).
>>>>>>>>
>>>>>>>> ∙ If I specify 1.0 for the time interval, my method gets called 20
>>>>>>>> times/sec.
>>>>>>>> ∙ If I specify 20.0 for the time interval, my method gets called 1
>>>>>>>> time/sec.
>>>>>>>> ∙ If I specify 100.0 for the time interval, my method gets called 5
>>>>>>>> times/sec.
>>>>>>>> ...etc.
>>>>>>>>
>>>>>>>> Here is my only invocation, called once and nevermore:
>>>>>>>>
>>>>>>>>  NSTimer *newTimer = [NSTimer timerWithTimeInterval:1.0  // should be
>>>>>>>> 1/sec
>>>>>>>>                                              target:self
>>>>>>>>                                            selector:@selector(newData:)
>>>>>>>>                                            userInfo:nil
>>>>>>>>                                             repeats:YES];
>>>>>>>>  [[NSRunLoop mainRunLoop] addTimer:newTimer
>>>>>>>>                            forMode:NSRunLoopCommonModes];
>>>>>>>
>>>>>>> Sounds like multiple timers are being installed. Set a breakpoint that
>>>>>>> logs when hit.
>>>>>>>
>>>>>>
>>>>>> On break, It's always the same timer. This is with time interval set to
>>>>>> 20.0:
>>>>>>
>>>>>> <timer id>                   <interval>       <fire date>
>>>>>> <__NSCFTimer: 0x60000323c600>   1.000000   Wed Apr 29 13:50:40 2020
>>>>>> <__NSCFTimer: 0x60000323c600>   1.000000   Wed Apr 29 13:50:41 2020
>>>>>> <__NSCFTimer: 0x60000323c600>   1.000000   Wed Apr 29 13:50:42 2020
>>>>>> . . .
>>>>>>
>>>>>
>>>>> I put a break directly after the creation of the timer, and introspection
>>>>> already shows the wrong value for the time interval! And since
>>>>> .timeInterval is a readonly attribute, I cannot force it to the correct
>>>>> value, nor is there a -setTimeInterval: method.
>>>>>
>>>>> Argh...
>>>>> -Carl
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>>
>>>>> Cocoa-dev mailing list (email@hidden
>>>>> <mailto:email@hidden>)
>>>>>
>>>>> Please do not post admin requests or moderator comments to the list.
>>>>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>>>> <http://lists.apple.com/>
>>>>>
>>>>> Help/Unsubscribe/Update your Subscription:
>>>>>
>>>>> This email sent to email@hidden
>>>>
>>>> _______________________________________________
>>>>
>>>> Cocoa-dev mailing list (email@hidden
>>>> <mailto:email@hidden>)
>>>>
>>>> Please do not post admin requests or moderator comments to the list.
>>>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>>> <http://lists.apple.com/>
>>>>
>>>> Help/Unsubscribe/Update your Subscription:
>>>>
>>>> This email sent to email@hidden
>>>
>>
>> _______________________________________________
>>
>> Cocoa-dev mailing list (email@hidden)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden

_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >NSTimer +timerWithTimeInterval: (From: Carl Hoefs via Cocoa-dev <email@hidden>)
 >Re: NSTimer +timerWithTimeInterval: (From: Steve Mills via Cocoa-dev <email@hidden>)
 >Re: NSTimer +timerWithTimeInterval: (From: Carl Hoefs via Cocoa-dev <email@hidden>)
 >Re: NSTimer +timerWithTimeInterval: (From: Carl Hoefs via Cocoa-dev <email@hidden>)
 >Re: NSTimer +timerWithTimeInterval: (From: Alex Zavatone via Cocoa-dev <email@hidden>)
 >Re: NSTimer +timerWithTimeInterval: (From: Carl Hoefs via Cocoa-dev <email@hidden>)
 >Re: NSTimer +timerWithTimeInterval: (From: Ken Thomases via Cocoa-dev <email@hidden>)

  • Prev by Date: Re: [OT] NSTimer +timerWithTimeInterval:
  • Next by Date: Re: NSTimer +timerWithTimeInterval:
  • Previous by thread: Re: NSTimer +timerWithTimeInterval:
  • Next by thread: Re: NSTimer +timerWithTimeInterval:
  • Index(es):
    • Date
    • Thread