我对目标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];
感谢您的帮助
答案 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)
以下是为什么这不起作用的可能性:
你声称你在其他地方初始化了startHourLabel,但是,如果它是来自nib文件的标签,你根本不应该初始化它。它应声明为IBOutlet,并通过接口构建器连接到nib中的标签。
如果它不是笔尖中的标签,即您是故意以编程方式创建它,则需要检查初始化标签的地址,并检查传入checkRedColorText的标签的地址。 NSLog在初始化时的地址和checkRedColorText中的地址,或者用调试器检查它。