不可变实例、可变实例、copy与mutableCopy

代码:

#import <Foundation/Foundation.h>

// 不论一个实例是不可变实例还是可变实例
// 通过向该实例发送copy消息,得到的实例是不可变实例
// 通过向该实例发送mutableCopy消息,得到的实例是可变实例

// 在非ARC环境下
// 通过向实例发送copy或mutableCopy消息得到的实例需要手工调用release或autorelease方法

void stringCopy(void);
void stringMutableCopy(void);
void mutableStringCopy(void);
void mutableStringMutableCopy(void);

int main(int argc, const char* argv[]) {
    stringCopy();
    stringMutableCopy();
    mutableStringCopy();
    mutableStringMutableCopy();
    return 0;
}

void stringCopy(void) {
    NSLog(@"NSString copy:");
    NSString* stringA = [[NSString alloc] initWithFormat:@"Objective-C"];

    // 对于不可变实例而言,向其发送一条copy消息,返回的实例依然是不可变实例,并且就是原不可变实例本身
    // 该复制方式为浅复制
    NSString* stringB = stringA.copy;

    // 原不可变实例的引用计数器的值加1
    // 从copy消息返回的不可变实例的引用计数器的值与原不可变实例的引用计数器的值加1后的值相同
    NSLog(@"Address(stringA) = %p, retainCount(stringA) = %lu", stringA, stringA.retainCount);
    NSLog(@"Address(stringB) = %p, retainCount(stringA) = %lu", stringB, stringB.retainCount);

    // 原不可变实例的指针与从copy消息返回的不可变实例的指针相同,指向同一块内存区域
    NSLog(@"Address(stringA) == Address(stringB): %@", stringA == stringB ? @"YES" : @"NO");

    [stringA release];
    [stringB release];
}

void stringMutableCopy(void) {
    NSLog(@"NSString mutableCopy:");
    NSString* stringA = [[NSString alloc] initWithFormat:@"Objective-C"];

    // 对于不可变实例而言,向其发送一条mutableCopy消息,返回的实例是一个新的可变实例
    // 该复制方式为深复制
    NSMutableString* stringB = stringA.mutableCopy;

    // 原不可变实例的引用计数器值不变
    NSLog(@"Address(stringA) = %p, retainCount(stringA) = %lu", stringA, stringA.retainCount);

    // 从mutableCopy消息返回的新的可变实例的引用计数器为1
    NSLog(@"Address(stringB) = %p, retainCount(stringA) = %lu", stringB, stringB.retainCount);

    // 原不可变实例的指针与从copy消息返回的可变实例的指针不同,不指向同一块内存区域
    NSLog(@"Address(stringA) == Address(stringB): %@", stringA == stringB ? @"YES" : @"NO");

    [stringA release];
    [stringB release];
}

void mutableStringCopy(void) {
    NSLog(@"NSMutableString copy:");
    NSMutableString* stringA = [[NSMutableString alloc] initWithFormat:@"Objective-C"];

    // 对于可变实例而言,向其发送一条copy消息,返回的实例是一个新的不可变实例
    // 该复制方式为深复制
    NSString* stringB = stringA.copy;

    // 原可变实例的引用计数器的值不变
    NSLog(@"Address(stringA) = %p, retainCount(stringA) = %lu", stringA, stringA.retainCount);

    // 从mutableCopy消息返回的新的可变实例的引用计数器为1
    NSLog(@"Address(stringB) = %p, retainCount(stringA) = %lu", stringB, stringB.retainCount);

    // 原可变实例的指针与从copy消息返回的不可变实例的指针不同,不指向同一块内存区域
    NSLog(@"Address(stringA) == Address(stringB): %@", stringA == stringB ? @"YES" : @"NO");

    [stringA release];
    [stringB release];
}

void mutableStringMutableCopy(void) {
    NSLog(@"NSMutableString mutableCopy:");
    NSMutableString* stringA = [[NSMutableString alloc] initWithFormat:@"Objective-C"];

    // 对于可变实例而言,向其发送一条mutableCopy消息,返回的实例是一个新的不可变实例
    // 该复制方式为深复制
    NSMutableString* stringB = stringA.mutableCopy;

    // 原可变实例的引用计数器的值不变
    NSLog(@"Address(stringA) = %p, retainCount(stringA) = %lu", stringA, stringA.retainCount);

    // 从mutableCopy消息返回的新的可变实例的引用计数器为1
    NSLog(@"Address(stringB) = %p, retainCount(stringA) = %lu", stringB, stringB.retainCount);

    // 原可变实例的指针与从mutableCopy消息返回的可变实例的指针不同,不指向同一块内存区域
    NSLog(@"Address(stringA) == Address(stringB): %@", stringA == stringB ? @"YES" : @"NO");

    [stringA release];
    [stringB release];
}

输出:

NSString copy:
Address(stringA) = 0x100106800, retainCount(stringA) = 2
Address(stringB) = 0x100106800, retainCount(stringA) = 2
Address(stringA) == Address(stringB): YES
NSString mutableCopy:
Address(stringA) = 0x100106800, retainCount(stringA) = 1
Address(stringB) = 0x10010e1a0, retainCount(stringA) = 1
Address(stringA) == Address(stringB): NO
NSMutableString copy:
Address(stringA) = 0x10010e290, retainCount(stringA) = 1
Address(stringB) = 0x10010e1e0, retainCount(stringA) = 1
Address(stringA) == Address(stringB): NO
NSMutableString mutableCopy:
Address(stringA) = 0x10010e290, retainCount(stringA) = 1
Address(stringB) = 0x10010e2f0, retainCount(stringA) = 1
Address(stringA) == Address(stringB): NO
时间: 2024-10-13 05:17:30

不可变实例、可变实例、copy与mutableCopy的相关文章

关于:1.指针与对象;2.深浅拷贝(复制);3.可变与不可变对象;4.copy与mutableCopy的一些理解

最近对深浅拷贝(复制)做了一些研究,在此将自己的理解写下来,希望对大家有所帮助.本人尚处在摸索阶段,希望各位予以指正. 本文包括如下方向的探索: 1.指针与对象: 2.深/浅拷贝(复制): 3.可变/不可变对象: 4.Objective-C中的copy与mutableCopy方法. 一.指针与对象 在初始学习编程的时候,对于绝大多数面向对象编程的语言,这都是个绕不开的重点与难点.非常惭愧的是对它的认识我一直是不够的,并且感觉这项技术有许多的内容可以挖掘.说这是面向对象编程的核心思想也不为过.很多

Objective-C Objective-C中的指针,及对象的直接指向,copy和mutablecopy

1.Objective-C的指针世界 OC一直是人感觉比较变态的一门语言,为什么呢?因为它的每个变量都是指针型,多的都几乎让人忘了那个*的存在了. 所以常常a=b这个等号让我产生错觉,总以为a从b那拷贝了一份. 然而这的的确确,却是个指针.a这个变量存的内容是b所在的地址. 比如我定义了一个Student的Class,new了stu1和stu2,并把stu2=stu1,那当两者任何一个进行修改时,两个变量的内容都会修改. Student *stu1=[[Student alloc]init];

探讨NSString和NSMutableString的内存问题以及copy和MutableCopy两个方法

NSString: 1 //main.m 2 #import <Foundation/Foundation.h> 3 4 int main(int argc, const char * argv[]) { 5 @autoreleasepool { 6 7 NSString *str1 = @"aaa"; 8 NSString *str2 ; 9 NSString *str3 ; 10 NSString *str4 ; 11 NSString *str5 ; 12 NSStr

IOS开发之copy与MutableCopy

在开发工程中,很多时候我们要创建对象的副本,要创建副本,对象所在的类必须遵守 NSCopying 和 NSMutableCopying 的协议: @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end 一般Foundation的类都遵守这两个协议,都可以直接复制. 复制分多种情况 一:非

Copy和MutableCopy

//    一: copy 与 retain 的区别 //    谁才有引用计数的概念: //    1. 堆区空间才有引用计数概念. //    2. 堆区的对象才会有引用计数. //%ld: - 1           %lu:18446744073709551615 //retain:始终是浅拷贝.引用计数每次加一. //返回对象是否可变与被复制的对象保持一致. //copy:对于可变对象为深拷贝,引用计数不改变; //对于不可变对象是浅拷贝,引用计数每次加一. //始终返回一个不可变对象

copy 和 mutableCopy

retain 和 copy 的区别. copy copy是通过旧对象创建一个新对象,新对象引用计数器为1,与旧对象的引用计数无关. retain retain是创建一个指针,对象引用计数加1.retain 出来的指针和原对象的指针指向的内存地址是相同的. 如何实现copy 并不是所有对象都可以进行copy.mutableCopy .对象如果可以被copy 则需要遵守NSCopying , 如果对象可以被mutableCopying 则需要遵从 NSMutableCopying.如果即可以被cop

Objective-C语法之copy和mutablecopy

#pragma mark 演示字符串的copy //深拷贝--对象拷贝--内容拷贝(产生新对象)新对象计数器+1,原对象不变 void stringmutableCopy(){ //string = 1 NSString *string = [[NSString alloc]initWithFormat:@"age is %i", 10]; //str = 1 //产生了一个新对象,原对象的计数器不变 NSMutableString *str = [string mutableCopy

深浅拷贝的应用-copy、mutableCopy

ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController //如果想让list成为一个可变的数组,需要把copy变成retain,因为copy之后的对象永远都只是一个不可变的对象 @property (nonatomic,copy)NSMutableArray *list; @end ViewController.m /* 拷贝:复制一个对象->变成另外一个对象 深拷贝:复制

copy 与 retain的区别,以及copy与mutablecopy的区别

copy 与 retain的区别 copy: 建立一个索引计数为1的对象,然后释放旧对象      retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 Copy其实是建立了一个相同的对象,而retain不是:比如一个NSString对象,地址为0×1111,内容为@”STR”, Copy到另外一个NSString之 后,地址为0×2222,内容相同,新的对象retain为1, 旧有对象没有变化 而retain到另外一个NSString之 后,地址相同(建立一个指针