Re: NSTimer +timerWithTimeInterval:
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