Objective-C和Sprite Kit游戏开发从入门到精通
上QQ阅读APP看书,第一时间看更新

4.8 对象复制与传递

我们已经讨论了在Objective-C中如何创建类、如何创建类的实例(对象),以及类的继承等相关主题;接下来我们会讨论一些关于类和对象的应用问题。

■4.8.1 对象的复制

接下来,我们将继续使用CRobot类来演示对象的应用问题。首先,看下面的代码,我们会使用赋值运算符来复制对象。

    CRobot *robot5 = [[CRobot alloc] init];
    robot5.name = @"No.5";
    CRobot *robot6 = [[CRobot alloc] init];
    robot6 = robot5;
    NSLog(@"%@ , %@\n", robot5.name, robot6.name);
    //
    robot6.name = @"No.6";
    NSLog(@"%@ , %@\n", robot5.name, robot6.name);

从代码执行的结果中,我们可以看到,第一个NSLog()函数显示“No.5 , No.5”。然后,当我们修改robot6.name的值以后,第二个NSLog()函数显示“No.6 , No.6”,也就是说,当我们修改robot6对象的值时,robot5对象的值也“变化”了,这是为什么呢?

实际上,我们说过,对象就是指针!当我们将一个对象赋值给另一个对象时,实际执行的是“浅复制”,也就是复制了对象的指针(引用),这样,代码中的robot5和robot6对象实际上是指向同一内存区域,也就是同一个对象体。所以,当我们修改其中一个对象的值时,实际会同时反映到两个对象的引用中。

如果我们需要完全复制一个全新的对象,即对象的“深复制”操作,有两个方法,一个方法是通过实现NSCopying协议,另一个方法就是通过归档来实现,稍后,我们会讨论相关内容。

■4.8.2 对象作为参数

我们已经看到对象在赋值时的默认表现,即进行浅复制,而这一特性在对象作为函数或方法的参数时也会有着相同的表现。通过对象向函数或方法传递数据时,实际上传递的是对象的引用,此时,在函数或方法中对这个对象的操作应该注意:

❑ 通过引用传递对象,可以提高数据的传递效率,因为只传递指针,而不需要复制全部数据。

❑ 在函数或方法中对于对象的修改,会直接反映到外部对象,应注意代码的目的是否确实是这样。

下面的代码,演示了CRobot对象作为函数参数的应用,大家可以在main.m文件中进行相关测试。首先是robotRename()函数,如下面的代码。

    void robotRename(CRobot* robot) {
        if (robot ! = nil) robot.name =  @"新的名字";
    }

接下来,我们在main()函数中使用robotRename()函数,如下面的代码。

    int main(int argc, const char * argv[])
    {
        @autoreleasepool {
            CRobot *robot5 = [[CRobot alloc] init];
            robot5.name = @"No.5";
            robotRename(robot5);
            NSLog(robot5.name);
        }
        return 0;
    }