关闭

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

标签: objective-cios
1608人阅读 评论(0) 收藏 举报
分类:

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]);

    

    // strstring不是相同对象

    // 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);

    

    [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 Studentnamecopy

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 Studentcopy

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


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:631308次
    • 积分:9407
    • 等级:
    • 排名:第1998名
    • 原创:272篇
    • 转载:235篇
    • 译文:14篇
    • 评论:31条
    博客专栏
    最新评论