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

代码:

#import <Foundation/Foundation.h>

// 本例中
// 将诸如NSString、NSDictionary等类的实例称为不可变实例
// 将诸如NSMutableString、NSMutableDictionary等类的实例称为可变实例


// 不论这个实例是不可变实例还是可变实例
// 调用该实例的opy方法,得到的实例是不可变实例
// 调用该实例的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

 

转载于:https://www.cnblogs.com/xwoder/p/4469512.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值