Abh*_*ert 13 c cocoa objective-c grand-central-dispatch
我是一名具有很少C/C++经验(并且没有培训)的Objective-C开发人员,今天我遇到了一些奇怪的硬编码数值.
我确定这是一个简单/愚蠢的问题,但有人可以解释为什么这样做:
NSDate *start = [NSDate date];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
NSLog(@"seconds: %f", [start timeIntervalSinceNow]);
});
// output: seconds: -1.0001
Run Code Online (Sandbox Code Playgroud)
这也有效(注意秒数已经改变):
NSDate *start = [NSDate date];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
NSLog(@"seconds: %f", [start timeIntervalSinceNow]);
});
// output: seconds: -2.0001
Run Code Online (Sandbox Code Playgroud)
但这是立即执行的:
NSDate *start = [NSDate date];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 4 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
NSLog(@"seconds: %f", [start timeIntervalSinceNow]);
});
// output: seconds: -0.0001
Run Code Online (Sandbox Code Playgroud)
但是,使用4.0而不是4修复它:
NSDate *start = [NSDate date];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 4.0 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
NSLog(@"seconds: %f", [start timeIntervalSinceNow]);
});
// output: seconds: -4.0001
Run Code Online (Sandbox Code Playgroud)
为什么1和2正确地转换为相关的双值,但更大的数字(我测试3和4)似乎表示为0?
我正在使用Xcode 4.2进行编译,配置为使用LLVM 3.0.
编辑:
dispatch_time_t定义为:
typedef uint64_t dispatch_time_t;
Run Code Online (Sandbox Code Playgroud)
而dispatch_time是:
dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta);
Run Code Online (Sandbox Code Playgroud)
NSEC_PER_SEC是:
#define NSEC_PER_SEC 1000000000 /* nanoseconds per second */
Run Code Online (Sandbox Code Playgroud)
Aus*_*oke 25
一秒钟内有1,000,000,000纳秒,所以我假设它NSEC_PER_SEC被定义为1000000000.
4 是类型的 int4.0 是类型的 double现在假设一个int包含32位,a的范围int将是[-2,147,483,648 to 2,147,483,647]
4000000000 > 2147483647因此,您将导致int溢出,这导致该值设置为0.
编辑:我可能会更好地表达上述声明.溢出可能导致int(假设它的大小为32位,如上所述)等于该值-294967296,并将dispatch_time任何值<= 0视为0秒.这就是上面的"0"来自哪里.
甲double变量可以比保持较大的值int,并且是能够存储的值的近似值4000000000.
前两个工作因为1*10 ^ 9和2*10 ^ 9符合有符号的32位int.但是,4*10 ^ 9将不适合带符号的32位int.
4.0*10 ^ 9有效,因为浮点可以表示该值.
我希望这也会起作用:
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, ((int64_t)4) * NSEC_PER_SEC);
Run Code Online (Sandbox Code Playgroud)