您的位置:首页 > 移动开发 > Objective-C

Object-C对象复制:copy与mutableCopy、NScopying与NSMutableCopy

2015-01-14 11:06 447 查看
1、copy与mutableCopy

#import <Foundation/Foundation.h>

int main(int argc , char * argv[])
{
@autoreleasepool{
NSMutableString* book = [NSMutableString
stringWithString:@"疯狂iOS讲义"];
// 复制book字符串的可变副本
NSMutableString* bookCopy = [book mutableCopy];
// 对副本修改,对原字符串没有任何影响
[bookCopy replaceCharactersInRange:
NSMakeRange(2, 3)
withString:@"Android"];
// 此处看到原字符串的值并没有改变
NSLog(@"book的值为:%@" , book);
// 字符串副本发生了改变。
NSLog(@"bookCopy的值为:%@" , bookCopy);
NSString* str = @"fkit";
// 复制str(不可变字符串)的可变副本
NSMutableString* strCopy = [str mutableCopy]; //①
// 向可变字符串后面追加字符串
[strCopy appendString:@".org"];
NSLog(@"%@" , strCopy);
// 调用book(可变字符串)的copy方法,程序返回一个不可修改的副本
NSMutableString* bookCopy2 = [book copy]; //②
// 由于bookCopy2是不可修改的,因此下面代码将会出现错误
[bookCopy2 appendString:@"aa"];
}
}

2、NSCopying与NSMutableCopy协议
为了保证一个对象可以调用copy方法来复制自身的不可变副本,通常要做如下事情

1)该类实现NSCopying协议

2)该类实现copyWithZone:方法

为了保证对象可调用mutableCopy方法,做如下事情:

1)该类实现NSMutableCopying协议

2)该类实现copyWithZone:方法

实例代码:

//.h
#import <Foundation/Foundation.h>

@interface FKDog : NSObject <NSCopying>
@property (nonatomic , strong) NSMutableString* name;
@property (nonatomic , assign) int age;
@end

//.m
#import "FKDog.h"

@implementation FKDog
@synthesize name;
@synthesize age;
//- (id)copyWithZone:(NSZone*)zone
//{
// NSLog(@"--执行copyWithZone--");
// // 使用zone参数创建FKDog对象
// FKDog* dog = [[[self class] allocWithZone:zone] init];
// dog.name = self.name;
// dog.age = self.age;
// return dog;
//}
// 为深复制实现的copyWithZone:方法
- (id)copyWithZone:(NSZone*)zone
{
NSLog(@"--执行copyWithZone--");
// 使用zone参数创建FKDog对象
FKDog* dog = [[[self class] allocWithZone:zone] init];
// 将原对象的name实例变量复制一份副本后赋值给新对象的name实例变量
dog.name = [self.name mutableCopy];
dog.age = self.age;
return dog;
}
@end使用
#import <Foundation/Foundation.h>
#import "FKDog.h"

int main(int argc , char * argv[])
{
@autoreleasepool{
// 创建一个FKDog对象
FKDog* dog1 = [FKDog new];
dog1.name = [NSMutableString stringWithString:@"旺财"];
dog1.age = 20;
// 复制副本
FKDog* dog2 = [dog1 copy];
// 复制对象的可变副本
// FKDog* dog2 = [dog1 mutableCopy];
dog2.name = [NSMutableString stringWithString:@"snoopy"];
dog2.age = 12;
NSLog(@"dog1的名字为:%@" , dog1.name);
NSLog(@"dog1的年龄为:%d" , dog1.age);
NSLog(@"dog2的名字为:%@" , dog2.name);
NSLog(@"dog2的年龄为:%d" , dog2.age);
}
}

如果父类继承NSCopying协议,子类同样需要重写NSCopying协议时,需要在copyWithZone:方法中调用父类的[super   copy]
3、深复制与浅复制

浅复制在子类中更改某个成员变量时,父类和子类都改变

深复制在子类中更改某个成员变量时,只改变子类的值,父类不改变

//浅复制
- (id)copyWithZone:(NSZone*)zone
{
NSLog(@"--执行copyWithZone--");
// 使用zone参数创建FKDog对象
FKDog* dog = [[[self class] allocWithZone:zone] init];
//①:浅复制
dog.name = self.name;
dog.age = self.age;
return dog;
}
// 为深复制实现的copyWithZone:方法
- (id)copyWithZone:(NSZone*)zone
{
NSLog(@"--执行copyWithZone--");
// 使用zone参数创建FKDog对象
FKDog* dog = [[[self class] allocWithZone:zone] init];
// 将原对象的name实例变量复制一份副本后赋值给新对象的name实例变量
//②:深复制
dog.name = [self.name mutableCopy];
dog.age = self.age;
return dog;
}

4、setter方法中使用copy选项
如:@property(nonatomic,copy)   NSMutableString* name;即如下代码所示

-(void) setName:(NSMutableString*) aname

{

    name = [aname  copy];

}

当在外部使用时,如果给name值appendString一个字符串,是不允许的,虽然name是NSMutableString对象,但是它的setter使用的是copy,所以,依然name是不可变的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Object-C 复制对象
相关文章推荐