复制对象、对象归档和单例

1、复制对象的基本概念 

·复制对象的基本概念 复制对象顾名思义,复制一个对象作为副本,它会开辟一块新的内存(堆内存)
 来存储副本对象,就像复制文件一样。即源对象和副本对象是两块不同的内存区
域。
·对象具备复制功能,必须实现 ·<NSCopying>协议
·<NSMutableCopying>协议 
·常用的可复制对象有:NSNumber、NSString、NSArray、NSDictionary、NSMutableDictionary、NSMutableArray、NSMutableString 
·复制对象的种类
·copy:产生对象的副本是不可变的
·mutableCopy:产生的对象副本是可变的


·创建一个数组(包含元素:one,two,three等),然后分别对它进行保留、 和拷贝操作,删除其中的一个元素,看看发生了什么?

NSMutableArray *mutableArray =[NSMutableArray arrayWithObjects:@"one",@"two",@"three", @"four", nil];
NSMutableArray *retainArray =[mutableArray retain];
[mutableArray removeLastObject];
for (NSString *string in retainArray) {
	NSLog(@"string : %@", string); 
} // 同⼀一块堆内存

NSMutableArray *mutableArray =[NSMutableArray arrayWithObjects:@"one", @"two",@"three", @"four", nil];
NSMutableArray *copyArray =[mutableArray mutableCopy];
[copyArray removeLastObject];
for (NSString *string in mutableArray) 
{
	NSLog(@"string : %@", string); 
} // 新的⼀一块堆内存


COPY和MUTABLECOPY的区别

·copy和mutableCopy的区别 ·前者返回一个不可变对象副本,后者返回一个可变对象副本
·示例:

NSArray *array = [NSArray arrayWithObjects:@"aaa",@"bbb",@"ccc", nil]; //返回不可变数组
NSArray *arrayCopy = [array copy];
//返回可变数组
NSMutableArray *mutableCopy = [array mutableCopy]; 
[mutableCopy addObject:@"ddd"]; 
NSLog(@"arrayCopy: %@",arrayCopy); 
NSLog(@"mutableCopy: %@",mutableCopy);

2、浅拷贝和深拷贝基本概念和用法

·深浅复制的基本概念 ·浅复制只复制对象的本身,对象里的属性、包含的对象不做复制。
·深复制则即复制对象本身,对象的属性也会复制一份。 

·Foundation框架中支持复制的类,默认是浅复制。


·例如: 一个数组包含了许多个对象,复制一个数组的副本,那么两个数组中的 元素是没复制的,指向的还是同一个对象。

NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:3];
for (int i=0; i<3; i++) {
     NSObject *obj = [[NSObject alloc] init];
     [array addObject:obj];
     [obj release];
}
for (NSObject *o in array) {
	NSLog(@"复制之前: retainCount: %lu",[o retainCount]);
}
NSArray *newArray = [array copy];
for (NSObject *o in newArray) {
	NSLog(@"复制之后: retainCount: %lu",[o retainCount]);
}

3、对象的自定义拷贝

·对象拥有复制特性,须实现NSCopying、NSMutableCopying协议,实现该 协议的copyWithZone:方法和mutableCopyWithZone:方法。

- (id)copyWithZone:(NSZone *)zone {
    User *user = [[[self class] allocWithZone:zone] init];
    user.data = _data;
    return user;
} // 返回的是不可变对象

- (id)mutableCopyWithZone:(NSZone *)zone {
	UserMutable *user = [[[self class] allocWithZone:zone] init]; user.data = _data;
	return user;
} // 返回的是可变对象

深、浅复制的不同实现
·Objective-C对象的深、浅拷贝的区别就在于你对copyWithZone的不同实现

- (id)copyWithZone:(NSZone *)zone {
// /**浅复制的实现**/
//    Person *p = [[[self class] allocWithZone:zone] init];
//    p.name = _name;
//    p.age = _age;
// return p;
/**深复制的实现**/
Person *p = [[[self class] allocWithZone:zone] init]; 
p.name = [_name copy];
p.age = [_age copy];
return p;
}

4、深、浅拷贝和RETAIN之间的总结

·copy、mutableCopy和retain之间的关系·Foundation可复制的对象,当我们copy的是一个不可变的对象时,它的作用相当于retain(cocoa做的内存优化)
·当我们使用mutableCopy时,无论源对象是否可变,副本是可变的,并且实现了真正意义上的拷贝
·当我们copy的是一个可变对象时,副本对象是不可变的,同样实现了真正意义上的拷贝 


复制对象总结

·复制对象的概念,浅复制、深复制的区别。 
·自定义对象如何支持复制,实现NSCopying协议。 
·自定义对象如何实现深复制和浅复制。 
·Foundation框架中支持复制的对象需要注意的地方。


5、对象归档的基本概念和用法

·概念: 对象归档是指将对象写入文件保存在硬盘上,当再次重新打开程序时, 可以还原这些对象。你也可以称它为对象序列化、对象持久化
·数据持久性的方式 ·NSKeyedArchiver——对象归档
·NSUserDefaults
·属性列表化( NSArray、NSDictionary保存文件) ·SQlite数据库、Core Data数据库
·归档的形式 
·对Foundation库中对象进行归档
·自定义对象进行归档(需要实现归档协议,NSCoding) 
·归档后的文件是加密的, 属性列表是明文的。


·我们就以数组为例,实现一个数组的序列化和反序列化

//   归档(序列化)
NSString *homeDirectory = NSHomeDirectory();
NSArray *array = @[@123, @456, @"999", @"000"];
NSString *directoryA = [homeDirectory stringByAppendingPathComponent:@"array.archive"];
if ([NSKeyedArchiver archiveRootObject:array toFile:directoryA]) {
    NSLog(@"archiver success");
}
// 解归档(反序列化)
NSArray *unArray = [NSKeyedUnarchiver unarchiveObjectWithFile:directoryA]; 
NSLog(@"new Array : %@", newArray);

自定义内容归档
·归档 
·使用NSData实例作为归档的存储数据
·添加归档的内容(设置key与value) 
·完成归档
·将归档数据存入磁盘中

·解归档 
·从磁盘读取文件,生成NSData实例
·根据Data实例创建和初始化解归档实例 
·解归档,根据key访问value的值

·自定义一个基本数据类型和一个objective-c对象类型,进行对象的归档和解归 档

// 归档 (序列化)
NSString *homePath = NSHomeDirectory();
NSString *filePath = [homePath stringByAppendingPathComponent:@"customContent.archive"]; 
NSMutableData *data = [NSMutableData data]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeFloat:50 forKey:@"weight"];
[archiver encodeObject:@"jack" forKey:@"name"]; 
[archiver finishEncoding];
[archiver release];
[data writeToFile:filePath atomically:YES];
// 解归档(反序列化)
NSData *content = [NSData dataWithContentsOfFile:filePath];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:content];
float weight = [unarchiver decodeFloatForKey:@"weight"];
NSString *name = [unarchiver decodeObjectForKey:@"name"];

自定义对象的归档基本概念

·自定义的对象要支持归档,需要实现NSCoding协议。 
·NSCoding协议有两个方法,encodeWithCoder 方法对对象的属性数据做编码处理。initWithCoder 解码归档数据来初始化对象 
·实现NSCoding协议后,就能通过NSKeyedArchiver归档。 
·示例:

// 解码方法
- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self != nil) {
        _name = [[aDecoder decodeObjectForKey:@"name"] copy];
        _age = [aDecoder decodeIntForKey:@"age"];
        _apples = [[aDecoder decodeObjectForKey:@"apples"] retain];
    }
    return self;
}

// 编码方法
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeObject:_apples forKey:@"apples"];
    [aCoder encodeInt:_age forKey:@"age"];
}

归档总结

·归档和解归档的两种方式 
·自定义对象如何归档,实现NSCoding协议。 
·归档后的文件是加密的。


6、单例设计模式

·基本概念 单例设计模式运用较为普遍、广泛且较为简单的设计模式之一,它的设计原理是:始终返回一个实例,即一个类始终只有一个实例。



创建单例的基本步骤

·创建单例设计模式的基本步骤 
·声明一个单件对象的静态实例,并初始化为nil。
·创建一个类的类工厂方法,生成一个该类的实例,当且仅当这个类的实例为nil时 
·覆盖allocWithZone:方法,确保用户(程序员)在直接分配和初始化对象时,不会产生另一个对象。
·实现NScopying协议,覆盖release、autorelease、retain、retainCount方法, 以此确保单例的状态。
·在多线程的环境中,注意使用@synchronized关键字,确保静态实例被正确的创建 和初始化。


单例的基本实现

·定义静态对象和工厂方法

//  定义⼀一个静态实例,并初始化为nil static File *shareFile = nil;
+ (File *)shareFile
{
@synchronized (self) { // 线程保护 
	// 如果实例为nil,则创建该实例 
	if (shareFile == nil) {
            shareFile = [[self alloc] init];
        }
}
    return shareFile;
}
// 覆盖allocWithZone:方法
+ (id)allocWithZone:(NSZone *)zone
{
    NSLog(@" nil %p", zone);
    @synchronized (self) {
        if (shareFile == nil) {
            shareFile = [super allocWithZone:zone];
            return shareFile;
         } 
     }
    return shareFile;
}
// 实现copy协议,覆盖与内存相关的方法
- (id)copyWithZone:(NSZone *)zone
{
    return self;
} // 实现copy协议,返回本身
- (id)retain
{
    return self; 
} // 返回本身
- (NSUInteger)retainCount
{
    return UINT_MAX;
} // 返回⼀一个无符号整型范围最大值
- (oneway void)release
{
} // 什么都不做
- (id)autorelease
{
    return self;
} // 返回对象本身




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值