IOS学习—深拷贝和浅拷贝
xg48
10年前
深拷贝就是生成一个新的对象,内容和原对象完全相同。浅拷贝即是指针的拷贝,生成一个新的指针指向原对象。
// // main.m // 深拷贝与浅拷贝 // // Created by on 15/4/10. // Copyright (c) 2015年 apple. All rights reserved. // #import <Foundation/Foundation.h> #import "Student.h" #import "GoodStudent.h" int main(int argc, const char * argv[]) { @autoreleasepool { /* 拷贝的意义: 在改变副本对象的时候,不会影响到原对象 定义: 深拷贝:就是拷贝出来一个新的对象,内容和原对象一样。 浅拷贝:其实就是指针的拷贝,没有一个新的对象生成,只是多了一个指向原对象的指针,将原对象的指针赋值给了新声明的指针,即,是一个指针的拷贝。 */ // 只有从不可变对象copy到不可变对象的时候才是浅拷贝,其他的都是深拷贝 NSString *string = @"abcde"; NSString *str = [string copy]; NSLog(@"string: %@", string); NSLog(@"str: %@", str); // 因为指向同一个对象,所以原对象的引用计数+1 NSLog(@"string和str是否是同一个对象: %d", string == str); // 由可变字符到不可变字符的copy是深拷贝 NSMutableString *mutableString = [NSMutableString stringWithFormat:@"abc%@", @"dddddd"]; NSString *str1 = [mutableString copy]; NSLog(@"mutableString和str1是否是同一个对象: %d", mutableString == str1); // mutalbeCopy都是深拷贝 NSString *str2 = @"abbbbbbb"; NSMutableString *mutableString1 = [str2 mutableCopy]; NSLog(@"str2和mutableString1是否是同一个对象: %d", str2 == mutableString1); // 由此可见,即使是不可变到不可变的mutableCopy也是深拷贝,进一步证明了mutableCopy是深拷贝 NSString *str3 = @"kkkkkkk"; NSString *string1 = [str3 mutableCopy]; NSLog(@"str3和string1是否是同一个对象: %d", str3 == string1); NSMutableString *myStr1 = [NSMutableString stringWithFormat:@"abc%d", 10]; NSMutableString *myStr2 = [myStr1 copy]; // 这里的myStr2实际是一个immutable对象,是不可变的,所以改变myStr2对象会报错 // [myStr2 appendString:@"fdsaf"]; NSLog(@"myStr1: %@", myStr1); NSLog(@"myStr2: %@", myStr2); NSLog(@"myStr1和myStr2是否是同一个对象: %d", myStr1 == myStr2); // 如果有改变副本的内容而保持原来的对象内容不变的话,那么就用copy属性 // 这里改变了mutableName但是stu的name属性值没变 Student *stu = [[Student alloc] init]; NSMutableString *mutableName = [NSMutableString stringWithFormat:@"aaaaaa%d", 10]; stu.name = mutableName; [mutableName appendString:@" fdsafdsafsad"]; NSLog(@"stu.name: %@", stu.name); NSLog(@"mutableName: %@", mutableName); NSLog(@"stu.name和mutableName是否是同一个对象: %d", stu.name == mutableName); Student *stu1 = [Student studentWithName:@"stu1"]; Student *stu2 = [stu1 copy]; NSLog(@"%@", stu1.name); NSLog(@"%@", stu2.name); stu2.name = @"stu2"; NSLog(@"%@", stu1.name); NSLog(@"%@", stu2.name); GoodStudent *goodStudent1 = [GoodStudent goodStudentWithAge:10 name:@"Jack"]; GoodStudent *goodStudent2 = [goodStudent1 copy]; goodStudent2.name = @"Tom"; goodStudent2.age = 20; NSLog(@"goodStudent1 -> name: %@, age: %ld", goodStudent1.name, goodStudent1.age); NSLog(@"goodStudent2 -> name: %@, age: %ld", goodStudent2.name, goodStudent2.age); } return 0; }
// // Student.h // 深拷贝与浅拷贝 // // Created by on 15/4/10. // Copyright (c) 2015年 apple. All rights reserved. // #import <Foundation/Foundation.h> @interface Student : NSObject <NSCopying> @property (nonatomic, copy) NSString *name; + (id)studentWithName:(NSString *)name; @end
// // Student.m // 深拷贝与浅拷贝 // // Created by on 15/4/10. // Copyright (c) 2015年 apple. All rights reserved. // #import "Student.h" @implementation Student + (id)studentWithName:(NSString *)name { // 这里右边需要写成self class这样,因为如果子类调用父类的这个方法的时候,就会产生相应的子类,而不是产生父类 // 左边不用动,这表现了面向对象的特点,多态 Student *stu = [[[self class] alloc] init]; stu.name = name; return stu; } - (id)copyWithZone:(NSZone *)zone { Student *copy = [[[self class] allocWithZone:zone] init]; copy.name = self.name; return copy; } @end
// // GoodStudent.h // 深拷贝与浅拷贝 // // Created by on 15/4/10. // Copyright (c) 2015年 apple. All rights reserved. // #import <Foundation/Foundation.h> #import "Student.h" @interface GoodStudent : Student @property (nonatomic, assign) NSInteger age; + (id)goodStudentWithAge:(int)age name:(NSString *)name; @end
// // GoodStudent.m // 深拷贝与浅拷贝 // // Created by on 15/4/10. // Copyright (c) 2015年 apple. All rights reserved. // #import "GoodStudent.h" @implementation GoodStudent + (id)goodStudentWithAge:(int)age name:(NSString *)name { GoodStudent *good = [GoodStudent studentWithName:name]; good.age = age; return good; } - (id)copyWithZone:(NSZone *)zone { // 一定要调用父类的方法 GoodStudent *copy = [super copyWithZone:zone]; copy.age = self.age; return copy; } @end