• OC之【深拷贝(mutableCopy)和浅拷贝(copy)】


    main.m文件

    #import <Foundation/Foundation.h>

    #import "Student.h"

    #import "GoodStudent.h"

    // copy语法的目的:改变副本的时候,不会影响到源对象

    #pragma mark 字符串的拷贝(深拷贝)

    // 深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

    void stringMutableCopy() {

        // string:1

        NSString *string = [[NSString alloc] initWithFormat:@"age is %i", 10];

        

        // 产生了一个新的对象,计数器为1。源对象的计数器不变。

        // str:1

        // string:1

        NSMutableString *str = [string mutableCopy];

        //NSLog(@"str:%zi", [str retainCount]);

        //NSLog(@"string:%zi", [string retainCount]);

        

        // str和string不是相同对象

        // NSLog(@"%i", str == string);

        

        [str appendString:@" abcd"];

        

        NSLog(@"string:%@", string);

        NSLog(@"str:%@", str);

        

        // str:0

        [str release];

        // string:0

        [string release];

    }

    #pragma mark 演示字符串的拷贝(浅拷贝)

    // 只有一种情况是浅拷贝:不可变对象调用copy方法时

    // 浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。

    void stringCopy() {

        NSString *string = [[NSString alloc] initWithFormat:@"age is %i", 10];

        NSLog(@"%zi", [string retainCount]);

        

        // copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身

        // 源对象计数器会+1

        // 在浅拷贝情况下,copy其实就相当于retain

        NSString *str = [string copy];

        NSLog(@"%zi", [string retainCount]);

        

        // NSLog(@"%i", str == string);

        //NSString并不受引用计数器机制管理

      //tring指向常量去,系统为了保护常量区的空间,把常量区的引用计数弄很大......如果用%d打印,会溢出,打印出来-1 此处%d(有黄色警报) == %iz(无警报哦)

        [str release];

        [string release];

    }

    #pragma mark 可变字符串的copy(深拷贝)

    void mutableStringCopy() {

        NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];

        

        // 会产生一个新对象,str计数器为1

        NSString *str = [string copy];

        

        [str release];

    }

    #pragma mark 可变字符串的MutableCopy(深拷贝)

    void mutableStringMutableCopy() {

        NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];

        

        // 会产生一个新对象,str计数器为1

        NSMutableString *str = [string mutableCopy];

        

        [str appendString:@"1234"];

        

        NSLog(@"str:%@", str);

        NSLog(@"string:%@", string);

        

        [str release];

    }

    #pragma mark Student的name的copy

    void studentNameCopy() {

        Student *stu = [[[Student alloc] init] autorelease];

        

        NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];

        

        stu.name = string;

        

        [string appendString:@"abcd"];

        

        NSLog(@"name=%@", stu.name);

        NSLog(@"string=%@", string);

    }

    #pragma mark Student的copy

    void studentCopy() {

        Student *stu1 = [Student studentWithName:@"stu1"];

        

        Student *stu2 = [stu1 copy];

        stu2.name = @"stu2";

        

        NSLog(@"stu1:%@", stu1);

        NSLog(@"stu2:%@", stu2);

        

        [stu2 release];

    }

    void goodStudentCopy() {

        GoodStudent *stu1 = [GoodStudent goodStudentWithAge:10 name:@"good1"];

        

        GoodStudent *stu2 = [stu1 copy];

        stu2.name = @"good2";

        stu2.age = 11;

        

        NSLog(@"stu1:%@", stu1);

        NSLog(@"stu2:%@", stu2);

    }

    int main(int argc, const char * argv[])

    {

        @autoreleasepool {

            goodStudentCopy();

        }

        return 0;

    }

    Student.h文件

    #import <Foundation/Foundation.h>

    @interface Student : NSObject <NSCopying>

    // copy代表set方法会release旧对象、copy新对象

    // 修改外面的变量,并不会影响到内部的成员变量

    // 建议:NSString一般用copy策略,其他对象一般用retain

    @property (nonatomic, copy) NSString *name;

    + (id)studentWithName:(NSString *)name;

    @end

    Student.m文件

    #import "Student.h"

    @implementation Student

    + (id)studentWithName:(NSString *)name {

        // 这里最好写[self class]

        Student *stu = [[[[self class] alloc] init] autorelease];

        stu.name = name;

        

        return stu;

    }

    - (void)dealloc {

        [_name release];

        

        [super dealloc];

    }

    #pragma mark description方法内部不能打印self,不然会造成死循环

    - (NSString *)description {

        return [NSString stringWithFormat:@"[name=%@]", _name];

    }

    #pragma mark copying协议的方法

    // 这里创建的副本对象不要求释放

    - (id)copyWithZone:(NSZone *)zone {

        Student *copy = [[[self class] allocWithZone:zone] init];

        

        // 拷贝名字给副本对象

        copy.name = self.name;

        

        return copy;

    }

    @end

    GoodStudent.h

    #import "Student.h"

    @interface GoodStudent : Student

    @property (nonatomic, assign) int age;

    + (id)goodStudentWithAge:(int)age name:(NSString *)name;

    @end

    GoodStudent.m

    #import "GoodStudent.h"

    @implementation GoodStudent

    + (id)goodStudentWithAge:(int)age name:(NSString *)name {

        GoodStudent *good = [GoodStudent studentWithName:name];

        

        good.age = age;

        

        return good;

    }

    - (NSString *)description {

        return [NSString stringWithFormat:@"[name=%@, age=%i]", self.name, _age];

    }

    - (id)copyWithZone:(NSZone *)zone {

        // 一定要调用父类的方法

        GoodStudent *copy = [super copyWithZone:zone];

        

        copy.age = self.age;

        

        return copy;

    }

    @end

    On the road。。。
  • 相关阅读:
    RE
    【LeetCode】198. House Robber
    【LeetCode】053. Maximum Subarray
    【LeetCode】152. Maximum Product Subarray
    【LeetCode】238.Product of Array Except Self
    【LeetCode】042 Trapping Rain Water
    【LeetCode】011 Container With Most Water
    【LeetCode】004. Median of Two Sorted Arrays
    【LeetCode】454 4Sum II
    【LeetCode】259 3Sum Smaller
  • 原文地址:https://www.cnblogs.com/ianhao/p/4425900.html
Copyright © 2020-2023  润新知