Objective-C将对象传递给函数总是通过引用或者通过值?

时间:2016-08-30 05:43:55

标签: ios objective-c

在objective-c中我传递NSMutableDictionary函数并在函数内修改它返回修改后的可变字典:

NSMutableDictionary *obj2 = [[NSMutableDictionary alloc]initWithObjectsAndKeys:@"hello",@"fname",nil];
[self callerDictionary:obj2];
NSLog(@"%@",obj2[@"fname"]);//printing "Hi"
-(void)callerDictionary:(NSMutableDictionary*)obj
{
    obj[@"fname"] = @"Hi";   
}

3 个答案:

答案 0 :(得分:1)

从技术上讲,Objective C总是通过值传递参数,就像C一样,但实际上当你传递一个对象时,你需要传递一个指针。虽然这个指针是通过值传递的,但Objective-C的语义与传递对象引用的效果相同;如果修改指针指向的objected,则修改调用上下文中指向的同一对象实例。 Objective C编程中使用的常用术语是“对象引用”,即使它实际上是指针值。

您可以从方法签名中的*看到它是一个指针(或常见用法中的对象引用)。如果要传递内部类型,例如int,那么它将按值传递,除非您明确声明该方法需要引用:

例如:

-(void) someFunction:(int *)intPointer {
    *intPointer = 5;
}

将被称为

int someInteger = 0;

[self someFunction: &someInteger];

// someInteger is now 5

与使用真实引用的Swift相比,可以看到指针值和真实对象引用之间的区别;

如果我有

-(void)someFunction:(NSString *)someString {
     int length = [someString length];
}

然后再做

NSMutableArray *array = [NSMutableArray new];
[someFunction: (NSString *)array];

我会得到一个运行时异常,因为数组没有length方法,但编译器无法确认我传递的类型,因为它是一个指针。

如果我尝试了Swift中的等价物,那么我将得到一个编译时错误,因为它知道类型强制总是会失败

答案 1 :(得分:0)

Objective C中的所有对象都通过引用传递。 所有C类型,如NSUInteger,double等按值传递

答案 2 :(得分:0)

C和Objective-C始终按值传递参数。始终通过引用(即指针)访问Objective-C对象。变量类型(int,指针等)与变量作为函数参数传递的方式之间存在差异。在两种情况下使用术语参考都可能导致混淆。

按值:

void f(int a) {
    a = 14;
}

int a = 5;

NSLog(@"%d", a);  // prints: 5

f(a);

NSLog(@"%d", a);  // prints: 5

值5被打印两次,因为函数f()被赋予{em> copy a,即5。函数中引用的变量是传入的变量不一样;这是一份副本。

在C ++中,您可以使用通过引用获取参数的函数。

按引用:

void f(int &a) {
    a = 14;
}

int a = 5;

NSLog(@"%d", a);  // prints: 5

f(a);

NSLog(@"%d", a);  // prints: 14

请注意函数签名中的&。在C ++中(但不是C,也不是Objective-C),这意味着参数通过引用传递。这意味着将a的引用(指针)传递给函数。在函数中,a变量被隐式取消引用(记住,它实际上是一个指针,但你不把它当作一个),并且在函数外声明的原始a变量会被更改。 / p>

在C和Objective-C中,将指针传递给函数在功能上等同于在C ++中使用引用参数。这是因为地址的副本被赋予函数(记住,参数仍然按值传递),并且该地址指向原始指针所执行的相同对象实例。您在函数中看不到任何显式指针解除引用的原因(类似于C ++引用)是因为对象访问的Objective-C语法总是隐式地解引用 - 在函数内部不会改变此行为。