在目标C中按值或引用传递参数

时间:2010-05-23 16:31:24

标签: objective-c pass-by-reference

我对目标c有点新意,我试图通过引用传递参数,但表现得像是一个值。你知道为什么这不起作用吗?

这是功能:

- (void) checkRedColorText:(UILabel *)labelToChange {
    NSComparisonResult startLaterThanEnd = [startDate compare:endDate];
    if (startLaterThanEnd == NSOrderedDescending){
        labelToChange.textColor = [UIColor redColor];
    }
    else{
        labelToChange.textColor = [UIColor blackColor];
    }

}

这就是电话:

UILabel *startHourLabel; // This is properly initialized in other part of the code
[self checkRedColorText:startHourLabel];

感谢您的帮助

5 个答案:

答案 0 :(得分:70)

Objective-C 支持按值传递参数。这里的问题可能已经修复(因为这个问题已经超过一年了)但我需要澄清一些关于论证和Objective-C的事情。

Objective-C是C的严格超集,这意味着C所做的一切,Obj-C也是如此。

通过快速浏览维基百科,您可以see Function parameters are always passed by value

Objective-C也不例外。这里发生的是每当我们将一个对象传递给一个函数(在本例中是一个UILabel *)时,我们在指针的地址传递值 contains

无论你做什么,它都将是你传递的价值。如果你想传递引用的值,你必须传递一个**对象(就像在传递NSError时经常看到的那样)。

这与标量相同,它们是按值传递的,因此您可以修改方法中收到的变量的值,并且不会更改传递给函数的原始变量的值。

以下是一个简化理解的例子:

- (void)parentFunction {
    int i = 0;
    [self modifyValueOfPassedArgument:i];
    //i == 0 still!
}

- (void)modifyValueOfPassedArgument:(NSInteger)j {
    //j == 0! but j is a copied variable. It is _NOT_ i
    j = 23;
    //j now == 23, but this hasn't changed the value of i.
}

如果您希望能够修改i,则必须通过执行以下操作传递引用的值:

- (void)parentFunction {
    int i = 0; //Stack allocated. Kept it that way for sake of simplicity
    [self modifyValueOfPassedReference:&i];
    //i == 23!
}

- (void)modifyValueOfPassedReference:(NSInteger *)j {
    //j == 0, and this points to i! We can modify i from here.
    *j = 23;
    //j now == 23, and i also == 23!
}

答案 1 :(得分:11)

Objective-C与Java一样,只有pass-by-value。与Java一样,始终通过指针访问对象。 “对象”永远不是直接值,因此您永远不会分配或传递对象。您正在按值传递对象指针。但这似乎不是问题 - 您正在尝试修改指针所指向的对象,这是完全允许的,并且与传值和传递引用无关。我发现您的代码没有任何问题。

答案 2 :(得分:0)

在objective-c中,没有办法按值传递对象(除非你明确地复制它,但这是另一个故事)。捅你的代码 - 你确定checkRedColorText:被调用吗?那么[startDate compare:endDate],它是否曾经不等于NSOrderedDescending? labelToChange是否为零?

答案 3 :(得分:0)

您是否在此行之间编辑了代码

UILabel *startHourLabel;

和这条线?

[self checkRedColorText:startHourLabel];

如果没有,问题是您正在重新声明您的startHourLabel变量,因此您将丢失之前的任何类型的初始化。你应该在这里得到编译错误。

答案 4 :(得分:0)

以下是为什么这不起作用的可能性:

  1. 您传入checkRedColorText的标签不是您认为的标签。
  2. 比较结果总是以同样的方式出现。
  3. ......实际上,没有3。
  4. 你声称你在其他地方初始化了startHourLabel,但是,如果它是来自nib文件的标签,你根本不应该初始化它。它应声明为IBOutlet,并通过接口构建器连接到nib中的标签。

    如果它不是笔尖中的标签,即您是故意以编程方式创建它,则需要检查初始化标签的地址,并检查传入checkRedColorText的标签的地址。 NSLog在初始化时的地址和checkRedColorText中的地址,或者用调试器检查它。