Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在非ARC中,对第一个参数为double的未声明方法的调用会导致数据损坏。_Ios_Objective C - Fatal编程技术网

Ios 在非ARC中,对第一个参数为double的未声明方法的调用会导致数据损坏。

Ios 在非ARC中,对第一个参数为double的未声明方法的调用会导致数据损坏。,ios,objective-c,Ios,Objective C,在非ARC中,对第一个参数为float的未声明方法的调用会导致不良行为 试试这个。使用以下方法创建一个类: - (bool) methodWithDouble:(double)value andArray:(NSArray*)ary { if (!ary) NSLog (@"Array is nil"); return true; } 现在调用该方法。为数组传入nil SomeClass *objSomeClass = [[SomeClass alloc] in

在非ARC中,对第一个参数为float的未声明方法的调用会导致不良行为

试试这个。使用以下方法创建一个类:

- (bool) methodWithDouble:(double)value andArray:(NSArray*)ary
{
    if (!ary)
        NSLog (@"Array is nil");
    return true;
}
现在调用该方法。为数组传入nil

SomeClass *objSomeClass = [[SomeClass alloc] init];
[objSomeClass methodWithDouble:21 andArray:nil];
[objSomeClass release];
您将注意到方法中的ary变为非nil。如果内存指针属于其他对象,If甚至可能崩溃


现在将double替换为int。这将正常工作。谁知道为什么

如果不查看方法声明,编译器只能从参数中猜测方法签名,并且您已经向它传递了21,即int,因此编译器猜测它正在调用

- (bool) methodWithDouble:(int)value andArray:(NSArray*)ary
这是完全错误的,passint和passdouble的调用转换几乎总是不同的。调用者可能会将4个字节推送到堆栈中,而被调用者希望堆栈中有8个字节,这会把一切都搞砸


如果将21更改为21.0,则在不查看方法声明的情况下,它应该可以工作,编译器只能从参数中猜测方法签名,并且您已将21传递给它,即int,因此编译器猜测它正在调用

- (bool) methodWithDouble:(int)value andArray:(NSArray*)ary
这是完全错误的,passint和passdouble的调用转换几乎总是不同的。调用者可能会将4个字节推送到堆栈中,而被调用者希望堆栈中有8个字节,这会把一切都搞砸

如果您将21更改为21.0的两倍,那么它应该会起作用

- (bool) methodWithDouble:(double)value andArray:(NSArray*)ary
在编译时从调用的位置不可见

[objSomeClass methodWithDouble:21 andArray:nil];
所以编译器猜测第一个参数是int,而不是将int 21隐式转换为double。如果在您的体系结构“sizeofint!”sizeofdouble'第二个参数将不位于methodWithDouble:和Array:所期望的位置。试着把这行改成

[objSomeClass methodWithDouble:(double)21 andArray:nil];

更新:

一些澄清

方法的参数通过堆栈推送。让我们假设

sizeof(int) == 4 
sizeof(double) == 8 
sizeof(void*) == 4 //pointers
所以,若编译器使用int参数调用某个方法,void*会将int的4个字节和指针的4个字节推送到堆栈中。若方法需要double,则void*它从堆栈中读取double的8个字节,并接收错误的值,然后接收指针的4个字节,并接收一些垃圾,因为推送的位置只有8个字节

- (bool) methodWithDouble:(double)value andArray:(NSArray*)ary
在编译时从调用的位置不可见

[objSomeClass methodWithDouble:21 andArray:nil];
所以编译器猜测第一个参数是int,而不是将int 21隐式转换为double。如果在您的体系结构“sizeofint!”sizeofdouble'第二个参数将不位于methodWithDouble:和Array:所期望的位置。试着把这行改成

[objSomeClass methodWithDouble:(double)21 andArray:nil];

更新:

一些澄清

方法的参数通过堆栈推送。让我们假设

sizeof(int) == 4 
sizeof(double) == 8 
sizeof(void*) == 4 //pointers

所以,若编译器使用int参数调用某个方法,void*会将int的4个字节和指针的4个字节推送到堆栈中。如果方法需要double,void*它从堆栈中读取double的8个字节,并接收错误的值,然后接收指针的4个字节,并接收一些垃圾,因为只有8个字节被推送。

运行此操作的硬件是什么?ARM还是x86上的模拟器?64位Mac上的64位模拟器,iOS 7.1 SDKAR您看到编译器警告了吗?如果没有,您是否已将其关闭?下面的两个答案都是可信的,应该给你一个警告。是的,我看到了警告。我在测试单元测试时遇到了这种情况,单元测试调用的方法未在SDK接口上公开。如果看到警告,请修复它们!你运行这个的硬件是什么?ARM还是x86上的模拟器?64位Mac上的64位模拟器,iOS 7.1 SDKAR您看到编译器警告了吗?如果没有,您是否已将其关闭?下面的两个答案都是可信的,应该给你一个警告。是的,我看到了警告。我在测试单元测试时遇到了这种情况,单元测试调用的方法未在SDK接口上公开。如果看到警告,请修复它们!但是如果NSARAY没有以零的形式通过呢?相反,它带有一个内存指针。当我通过21.0考试时,NSArray的成绩为零。int/double answer的Upvote将以nil通过,但未正确读取。请稍等,我将更新答案。方法的参数可以通过寄存器传递。即使double和long具有相同的大小,也可能会得到错误的结果,但是NSArray不作为零传递又如何呢?相反,它带有一个内存指针。当我通过21.0考试时,NSArray的成绩为零。int/double answer的Upvote将以nil通过,但未正确读取。请稍等,我将更新答案。方法的参数可以通过寄存器传递。即使双倍的和长的有相同的尺寸,它仍然可能得到错误的结果