复制对象的基本概念
对象复制
复制对象顾名思义,复制一个对象作为副本,它会开辟一块新的内存(堆内存)来存储副本对象,就像复制文件一样。即源对象和副本对象是两块不同的内存区域
<NSCopying>协议
<NSMutableCopying>协议
常用的可复制对象有:NSNumber、NSString、NSArray、NSDictionary等
复制对象的种类
copy:产生对象的副本是不可变的
mutableCopy:产生的对象副本是可变的
深浅拷贝的基本概念和用法
浅层复制(Shallow Copy)
浅拷贝
该操作不会复制对象
浅拷贝后,新对象,只是指向原有对象的一个引用
深层复制 (Deep Copy)
深拷贝
是一种会重新分配内存地址的拷贝方式
利用深拷贝,将会复制产生一个新的对象
自定义类实现深层拷贝步骤:
采用NSCopying协议
实现NSCopying协议
调用copy方法,实现深层复制
对象的自定义拷贝
内存管理的原则
如果使用alloc、copy或者new方法获得一个对象
那么该对象的保留计数器的值为1
而且你要负责释放该对象
copy方法
copy消息的作用,是复制对象
通知对象,创建一个全新的对象
并使新对象与接收copy消息的原来的那个对象一样
单例设计模式
基本概念
单例设计模式运用较为普遍、广泛且较为简单的设计模式之一,它的设计原理是始终返回一个实例,即一个类始终只有一个实例。
创建单例设计模式的基本步骤
声明一个单件对象的静态实例,并初始化为nil。
创建一个类的类工厂方法,生成一个该类的实例,当且仅当这个类的实例为nil时
覆盖allocWithZone:方法,确保用户(程序员)在直接分配和初始化对象时,不会产生另一个对象。
实现NScopying协议,覆盖release、autorelease、retain、retainCount方法,以此确保单例的状态
在多线程的环境中,注意使用@synchronized关键字,确保静态实例被正确的创建和初始化
Copy
main.m
#import <Foundation/Foundation.h>
#import "People.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
// NSMutableArray *array1 = [[NSMutableArray alloc] initWithObjects:@"one",@"two",@"three",@"four",nil];
// //
// NSMutableArray *array2 = [array1 retain];
//
// NSLog(@"array1 = %p,array2 = %p",array1,array2);
// NSLog(@"array1 retainCount = %ld",[array1 retainCount]);
// NSLog(@"array1 = %@",array2);
// [array2 removeLastObject];
// NSLog(@"array2 = %@",array1);
// NSMutableArray *array1 = [[NSMutableArray alloc] initWithObjects:@"one",@"two",@"three",@"four",nil];
// //
// NSMutableArray *array2 = [array1 mutableCopy];
//
// NSLog(@"array1 = %p,array2 = %p",array1,array2);
// NSLog(@"array1 retainCount = %ld",[array1 retainCount]);
// NSLog(@"array1 = %@",array1);
// [array2 removeLastObject];
// NSLog(@"array2 = %@",array2);
People *peo1 = [People new];
peo1.name = @"zhangsan";
peo1.age = @"34";
People *peo2 = [peo1 copy];
NSLog(@"peo1 = %p,peo2 = %p",peo1,peo2);
NSLog(@"peo1.name = %@,peo2.name= %@",peo1.name,peo2.name);
NSLog(@"peo1.name p = %p,peo2.name p = %p",peo1.name,peo2.name);
}
return 0;
}
People.m
#import "People.h"
@implementation People
@synthesize name=_name,age=_age;
- (id)copyWithZone:(NSZone *)zone{
//浅层拷贝
People *people = [[People alloc] init];
people.name =[_name mutableCopy];
people.age = [_age copy];
return people;
}
@end
People.h
#import <Foundation/Foundation.h>
@interface People : NSObject<NSCopying>
@property(nonatomic,assign) NSString *name;
@property(nonatomic,copy) NSString *age;
@end
Danli
main.m
#import <Foundation/Foundation.h>
#import "UserContext.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
//实例化一个对象
UserContext *userContext1 = [UserContext ShareUserContext];
UserContext *userContext2 = [[UserContext alloc] init];
UserContext *userContext3 = [userContext1 copy];
[userContext1 release];
[userContext1 release];
[userContext1 release];
[userContext1 retain];
NSLog(@"userContext1 = %p",userContext1);
NSLog(@"userContext2 = %p",userContext2);
NSLog(@"userContext3 = %p",userContext3);
//[userContext2 release];
//[userContext3 release];
//[userContext3 release];
// NSLog(@"");
}
return 0;
}
UserContext.m
#import "UserContext.h"
static UserContext *instancesContext=nil;
@implementation UserContext
//定义类方法,实现初始化
+(id)ShareUserContext{
//多线程时保证同一时间只有一个类可以操作该对象
@synchronized(self){
//判断对象是否存在
if(instancesContext == nil){
instancesContext = [[self alloc] init];
}
}
return instancesContext;
}
+(id)allocWithZone:(NSZone *)zone{
//多线程时保证同一时间只有一个类可以操作该对象
@synchronized(self){
//判断对象是否存在
if(instancesContext == nil){
instancesContext = [super allocWithZone:zone];
}
}
return instancesContext;
}
//覆盖拷贝方法
- (id)copyWithZone:(NSZone *)zone;{
return self; //确保copy对象也是唯一
}
- (oneway void)release
{
//重写计数释放方法
NSLog(@"release");
}
-(id)retain{
return self; //确保计数唯一
}
- (unsigned)retainCount
{
return UINT_MAX; //装逼用的,这样打印出来的计数永远为-1
}
- (id)autorelease
{
return self;//确保计数唯一
}
@end
UserContext.h
#import <Foundation/Foundation.h>
@interface UserContext : NSObject<NSCopying>
@property(nonatomic,assign) NSString *name;
@property(nonatomic,assign) NSString *password;
+(id)ShareUserContext;
@end