为id分配值并不坚持

时间:2014-05-05 15:18:01

标签: objective-c

我正在从一个文件中读取一个plist,并希望为文件中的值设置一些属性,但只有当它们不是nil时,我才想出一个小方法,但是它没有按预期工作:

- (void)assignNonNullValue:(id)value to:(id)target
{
    if (value) {
        target = value;
        NSLog(@"new value = %@", target);
    }
}

// ...

    NSString *foo = @"a";
    [self assignNonNullValue:@"b" to:foo];
    NSLog(@"foo=%@", foo);

我期待以下输出:

new value = b
foo=b

但我得到了:

new value = b
foo=a

为什么?

2 个答案:

答案 0 :(得分:1)

您正在更改方法中的目标值。它不会影响另一个范围内的foo值。它想要更改foo值,您需要将方法传递给它指向的位置。因此,当您更改方法时,它会影响foo值,因为您正在更改它指向的值。为了澄清我的解释,这里是代码

- (void)assignNonNullValue:(id)value to:(id *)target
{
    if(value != nil)
        *target = value;
}

使用id *真的很少见,因为id已经是指向对象的指针。 .Passing id *作为参数允许您更改它指向的值。所以,这将是永久性的。

在你做出改变之后我指出了。您需要将此方法称为

[self assignNonNullValue:@"b" to:&foo]; 

答案 1 :(得分:1)

这是另一种方法:

- (id)valueOrOriginalIfNull:(id)value original:(id)original {
    if (value) {
        return value;
    } else {
        return original;
    }
}

// ...

NSString *foo = @"a";
foo = [self valueOrOriginalIfNull:@"b" original:foo];
NSLog(@"foo=%@", foo);

原始方法失败的原因是参数是按值传递的。将target分配给方法内的其他值时,它对原始值没有影响。