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是不可变的
#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是不可变的
相关文章推荐
- iPhone/iOS中保存自定义对象(Custom Object/Custom Class)的数组(NSMutableArray/NSArray)到NSUserDefaults
- 对象复制copy与mutableCopy方法的区别
- IOS 根据对象属性值过滤数组中的元素 Filter NSMutableArray with object property
- 复制对象(一)copy和mutableCopy方法
- 19 NSCopying与NSMutableCopying协议+深复制和浅复制
- 数据类型与NSMutableArray添加对象(insertObject)引起的问题
- 探讨NSString和NSMutableString的内存问题以及copy和MutableCopy两个方法
- 对象的拷贝(NSCopying/NSMutableCopying)
- 条款12:复制对象时勿忘其每一个成分(Copy all parts of an object)
- 复制对象(一)copy和mutableCopy方法
- NSArray、NSMutableArray的copy、mutableCopy
- object-c中对NSMutableArray中存储对象的内存引用测试
- object-c中对NSMutableArray中存储对象的内存引用测试
- 复制对象(二)<NSCopying>协议和属性的copy特性
- 属性修饰copy;copy、mutableCopy;NSCopying NSMutableCopying
- 关于:1.指针与对象;2.深浅拷贝(复制);3.可变与不可变对象;4.copy与mutableCopy的一些理解
- 【已解决】iPhone/iOS中保存自定义对象(Custom Object/Custom Class)的数组(NSMutableArray/NSArray)到NSUserDefaults
- 条款12:复制对象时勿忘其每一个成分(Copy all parts of an object.)
- 复制对象(一)copy和mutableCopy方法
- Objective-C Copy语法(一)对于Objective-C 提供的类对象NSString/NSMutableString; NSArray/NSMutableArray...