昨天做項目的時候才發現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中關鍵字retain
,copy
和mutableCopy
的區別
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不同,可修改