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

Code:

#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];
}

Output:

NSString copy:
Address(stringA) = 0x100300270, retainCount(stringA) = 2
Address(stringB) = 0x100300270, retainCount(stringA) = 2
Address(stringA) == Address(stringB): YES
NSString mutableCopy:
Address(stringA) = 0x100400170, retainCount(stringA) = 1
Address(stringB) = 0x100400000, retainCount(stringA) = 1
Address(stringA) == Address(stringB): NO
NSMutableString copy:
Address(stringA) = 0x1001064a0, retainCount(stringA) = 1
Address(stringB) = 0x100106d70, retainCount(stringA) = 1
Address(stringA) == Address(stringB): NO
NSMutableString mutableCopy:
Address(stringA) = 0x100400000, retainCount(stringA) = 1
Address(stringB) = 0x100400250, retainCount(stringA) = 1
Address(stringA) == Address(stringB): NO


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值