zoukankan      html  css  js  c++  java
  • 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。。。
  • 相关阅读:
    SQL Server游标的使用
    SQL函数说明大全
    基本数据结构:链表(list)
    QT+C++实现连连看
    printf按8进制、16进制输出
    关于数据库优化问题收集
    SQL Server 查询处理中的各个阶段(SQL执行顺序) 转
    MFC消息机制
    _T() 和_L() _TEXT __T,L区别与联系详解
    Windows 各种控件使用心得
  • 原文地址:https://www.cnblogs.com/ianhao/p/4425900.html
Copyright © 2011-2022 走看看