Samoy的小窝


一只默默工作的程序猿


欢迎光临Samoy的小屋

关于Java和OC深浅复制的问题

昨天做项目的时候才发现Java和OC的深浅复制和Java的完全相反,Java的深复制是复制对象的地址,即两个对象有相同的内存地址(或者说这是同一个对象),而浅复制才是复制是一个新的对象,即新开辟一个新的内存地址,属性通过赋值传递。

下面是Java的一个例子:

public class Main {

    public static void main(String[] args) throws CloneNotSupportedException {
        Cat cat = new Cat();
        cat.setName("猫");
        //深复制
        Cat cat1 = cat;
        //浅复制
        Cat cat2 = (Cat) cat.clone();
        System.out.println("原对象cat的地址:" + cat);
        System.out.println("深复制cat1的地址:" + cat1);
        System.out.println("浅复制cat2的地址:" + cat2);
    }
}

class Cat implements Cloneable {

    private String name;

    public Cat() {

    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

而OC的深浅复制(OC通常称为拷贝)和Java正好相反:

  • 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。
  • 深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉。

OC中关键字retaincopymutableCopy的区别 retain:始终是浅复制。引用计数每次加一。返回对象是否可变与被复制的对象保持一致。 copy:对于可变对象为深复制,引用计数不改变;对于不可变对象是浅复制, 引用计数每次加一。始终返回一个不可变对象。 mutableCopy:始终是深复制,引用计数不改变。始终返回一个可变对象。

下面是OC的例子:

NSString* string = @"源字符串";  
NSString* stringCopy = [string copy];// stringCopy与string地址相同,retainCount+ 1  
NSMutableString* stringMCopy = [string mutablecopy];// stringMCopy与string地址不同  
   
NSMutableString* stringM1 = [stringMCopy copy];//地址与stringMCopy不同,且为不可修改
NSMutableString* stringM2 = [stringMCopy mutablecopy];//地址与stringMCopy不同,可修改 
欢迎在评论区留下您的见解~
最近的文章

一个Alert弹出框的工具类:AlertUtils

最近在做Android项目的时候总觉得系统提供的Alert弹出框代码过于繁琐,因此对系统Alert的代码进行了二次封装,这样以后开发的时候再也不用写很多代码了。代码如下:import android.app.Activity;import android.app.AlertDialog;import android.app.ProgressDialog;import android.content.DialogInterface;/** * Alert工具类 * * @author Sam...…

Android
更早的文章

使用CocoaPods卡在了"pod setup"界面的解决办法

有时候,我们在执行pod install或pod search命令时,会在终端偶现卡在’pod setup’界面的情况,其实,该情况也许并非真的卡住,下面给出两种解决方案。方案1: 在执行pod install命令时加上参数--verbose即:pod install 'ThirdPartyName' --verbose,可在终端详细显示安装信息,看到pod目前正在做什么(其实是在安装第三方库的索引),确认是否是真的卡住。2.进入终端家目录,输入ls -a可看到隐藏的pod文件夹,输入c...…

iOS