1

我在一个函数中有这 4 行代码

void * someFunction() {
        ... code to create invocation and other things
        CGRect aRect;
        [invocation getReturnValue:&aRect];
        finalValue = &aRect;
        return finalValue
}

基本上,我从 an 获取返回值NSInvocation并将返回值放在 aRect 的内存地址(即,AFAIK,应该在堆栈上)。返回值显然是一个CGRect。someFunction() 返回一个指向“任何东西”的指针。返回值可以是指向 int 的指针、指向 float 的指针或指向对象的指针。
所有提到的类型都正确返回,但我对 CGRect 有问题。

调试,aRect 设置正确后getReturnValue:

0x07127550 {{0, 20}, {320, 460}}

问题是当我返回时(代码与其他类型相同,int、long 或 object)

// the returned value is a generic pointer
void * returnValue = someFunction(arguments);
// cast this generic pointer to a CGRect pointer.
CGRect returnedRect = *(CGRect *)returnValue;

结果应该进入returnedRect,但再次调试,CGRect的值已损坏:

0x07127570 {{-1.99891, 2.61428e-38}, {-1.99891, 2.90066e-38}}

如您所见,内存地址是相同的,因此 rect 似乎已损坏。

如果我像这样更改第一个功能:

        CGRect *aRect = malloc(sizeOfReturnValue);
        [invocation getReturnValue:aRect];
        finalValue = aRect;
        return finalValue;

rect 正确传递而没有损坏。发生这种情况是因为,在这种情况下,我已经在堆上分配了结构

0x08070580 {{0, 20}, {320, 460}}

但是为什么在堆栈上设置它不起作用?对于 int、float、long 和 double,相同的代码可以正常工作。我错过了什么?

最后一点:我正在使用 ARC

谢谢

4

1 回答 1

3

在您的代码中

void * someFunction() {
        ... code to create invocation and other things
        CGRect aRect;
        [invocation getReturnValue:&aRect];
        finalValue = &aRect;
        return finalValue
}

您正在返回一个临时对象的地址并调用未定义的行为。一回来aRect就失效了。someFunction

当您访问它时,您使用的内存地址CGRect returnedRect = *(CGRect *)returnValue;不属于您,因此为什么您会看到奇怪的数字。

如果你想返回 CGRect,你可以直接返回对象。例如

CGRect someFunction() {
        ... code to create invocation and other things
        CGRect aRect;
        [invocation getReturnValue:&aRect];
        return aRect;
}

并像使用它一样

CGRect returnedRect = someFunction(arguments);
于 2013-08-08T23:13:57.410 回答