iOS阶段学习第21天笔记(ARC内存管理-Copy-代理)
iOS学习(OC语言)知识点整理
一、OC 中的ARC内存管理
1)ARC中释放对象的内存原则:看这个对象有没有强引用指向它
2)strong:强引用,默认情况下的引用都是强引用
3) weak:弱引用__weak
4)ARC环境下:与内存相关的代码都不能使用了,如果要在ARC环境下使用MRC内存管理代码 如:
[super delloc] 选中项目找到 Build Phases 菜单下的 Compile Sources 项 选中要转换的.m文件,
双击写入此行代码:-fno-objc-arc 即可
5)将MRC代码转换成ARC代码 操作:可以在Xcode 左上角Edit 菜单下的Convert中选择To Objective-C ARC…
项设置一下即可
6)如果两个对象的两个指针互相引用,会出现对象的内存无法释放的问题,解决办法:一端用strong,
一端用weak, 如果是peroperty中的基本类型用assign
7)ARC 操作 实例代码:
1 //main.m中的代码 2 Person *p1=[[Person alloc]init]; 3 //上一个对象没有强引用指向,内存会被释放掉 4 p1=[[Person alloc]init]; 5 NSLog(@"********"); 6 //错误的写法,表明有一个弱引用指向对象,这条语句执行完毕后对象就被释放了 7 __weak Person *p2=[[Person alloc]init]; 8 NSLog(@"+++======="); 9 10 //Person.h中的代码 11 #import <Foundation/Foundation.h> 12 @class Card; 13 @interface Person : NSObject 14 @property(nonatomic,strong)Card *card; 15 @property(nonatomic,strong)NSString *name; 16 @property(nonatomic,assign)int age; 17 @end 18 19 //Card.h中的代码 20 #import <Foundation/Foundation.h> 21 #import "Person.h" 22 @interface Card : NSObject 23 @property(nonatomic,weak)Person *person; 24 @end
二、copy与mutableCopy介绍
1)给字符串发送copy消息,得到的是一个不可变字符串(不管是给可变还是不可变字符串发送的消息)
2)给字符串发送mutableCopy消息,得到的是一个可变字符串(不管是给可变还是不可变字符串发送的消息)
3)字符串对象的copy操作 实例:
1 NSString *str1=@"Hello"; 2 NSString *str2=str1; 3 //对不可变字符串发送copy消息会得到一个新的不可变字符串 4 NSString *str3=[str1 copy]; 5 // [str3 appendString:@" shanghai"]; 6 //对不可变字符串发送mutableCopy消息后会得到一个新的可变字符串 7 NSMutableString *str4=[str1 mutableCopy]; 8 [str4 appendString:@" beijing"]; 9 NSLog(@"str4:%@",str4); 10 NSMutableString *mStr1=[NSMutableString stringWithString:str1]; 11 //对可变字符串发送copy消息会得到一个新的不可变字符串 12 NSString *mStr2=[mStr1 copy]; 13 //[mStr2 appendString:@"aaa"]; 14 15 //对可变字符串发送mutableCopy消息会得到一个新的可变字符串对象 16 NSMutableString *mStr3=[mStr1 mutableCopy]; 17 [mStr3 appendString:@"abc"]; 18 NSLog(@"mStr3=%@",mStr3);
4)实现对自定义对象的copy 实例代码:
1、定义一个QFCar 类 .h文件中的代码如下:
1 #import <Foundation/Foundation.h> 2 @interface QFCar : NSObject<NSCopying> 3 @property(nonatomic,copy)NSString *name; 4 @property(nonatomic,assign)int year; 5 -(void)print; 6 @end
2、.m文件中的代码如下:
1 #import "QFCar.h" 2 @implementation QFCar 3 //调用copy方法时会执行此协议方法 4 - (id)copyWithZone:(NSZone *)zone 5 { 6 //QFCar *car=[[QFCar allocWithZone:zone]init]; 7 //可以被子类继承,copy出来的就是子类的对象 8 //[self class]获取当前的类(对象) 9 QFCar *car=[[[self class] allocWithZone:zone]init]; 10 car.name=self.name; 11 car.year=self.year; 12 return car; 13 } 14 15 -(void)print 16 { 18 NSLog(@"name is %@, year is %d",_name,_year); 19 } 20 @end
3、main 文件中的实现代码:
1 QFCar *mCar=[[QFCar alloc]init]; 2 NSString *n1=@“宝马X6”; 3 NSMutableString *n=[[NSMutableString alloc]initWithString:n1]; 4 mCar.name=n; 5 mCar.year=2015; 6 [mCar print]; 7 [n appendString:@" kingkong"]; 8 [mCar print];
5)浅拷贝与深拷贝的介绍
1、 此两种拷贝是针对数字或字典集合来说的。
2、浅拷贝只拷贝数组对象,两个数组对象存放的是相同元素的地址,数组中的元素对象并没有被拷贝
3、深拷贝 不仅拷贝数组对象,数组中存放的元素对象也将被拷贝一份新的
6)深拷贝与浅拷贝实例代码
1 NSMutableArray *carList=[[NSMutableArray alloc]init]; 2 for(int i=0;i<5;i++){ 3 QFCar *car=[[QFCar alloc]init];//自定义的类对象 4 car.name=[NSString stringWithFormat:@“宝马X%d”,i+1]; 5 car.year=2011+i; 6 [carList addObject:car]; 7 } 8 9 //使用copy(mutableCopy)实现的是数组的浅拷贝(只拷贝数组对象,2个数组对象存放的是相同元素的地址,数组中的元素对象并没有被拷贝) 10 //NSMutableArray *array1=[carList mutableCopy]; 11 12 //浅拷贝 13 NSMutableArray *array1=[[NSMutableArray alloc]initWithArray:carList]; 14 15 //实现数组的深拷贝(不仅拷贝数组对象,数组中存放的元素对象也将被拷贝一份新的) 16 NSMutableArray *array2=[[NSMutableArray alloc]initWithArray:carList copyItems:YES]; 17 [[array2 lastObject] setName:@"shanghai"]; 18 for(QFCar *car in array2){ 19 [car print]; 20 } 21 NSLog(@"***********"); 22 for(QFCar *car in carList){ 23 [car print]; 24 }
三、OC 中的代理介绍
1)代理即自己声明方法自己不实现让别的类或对象去实现的一个过程,代理的目的在于降低代码的耦合性
2)代理一般都需要有一个协议(protocol)代理方需要遵守协议去实现方法
3)代理实例代码
1、创建两个类对象 HeadMaster(校长类) Teacher(教师类) ;教师类代理校长类的examine、
meeting、travle 三个方法
2、HeadMaster.h 文件中的代码实现如下:
1 #import <Foundation/Foundation.h> 2 @protocol MasterDelegate<NSObject> 3 -(void)examine; 5 -(void)meeting; 7 -(void)travle; 9 @end 11 @interface HeadMaster : NSObject 13 @property(nonatomic,strong)id<MasterDelegate> delegate; 15 -(void)masterExamine; 17 -(void)masterMeeting; 19 -(void)masterTravle; 21 @end
3、HeadMaster.m 文件中的代码实现如下:
1 #import "HeadMaster.h" 2 @implementation HeadMaster 3 -(void)masterExamine 4 { 5 if([_delegate conformsToProtocol:@protocol(MasterDelegate)]){ 6 if([_delegate respondsToSelector:@selector(examine)]){ 7 [_delegate examine]; 8 } 9 } 10 } 12 -(void)masterMeeting 13 { 14 if([_delegate conformsToProtocol:@protocol(MasterDelegate)]){ 15 if([_delegate respondsToSelector:@selector(meeting)]){ 16 [_delegate meeting]; 17 } 18 } 19 } 20 21 -(void)masterTravle 22 { 23 if([_delegate conformsToProtocol:@protocol(MasterDelegate)]){ 24 if([_delegate respondsToSelector:@selector(travle)]){ 25 [_delegate travle]; 26 } 27 } 28 } 29 @end
4、Teacher.h文件中的代码实现如下:
1 #import <Foundation/Foundation.h> 2 #import "HeadMaster.h" 3 @interface Teacher : NSObject<MasterDelegate> 4 @end
5、Teacher.m 文件中的代码实现如下:
1 #import "Teacher.h" 2 @implementation Teacher 3 -(void)examine 4 { 5 NSLog(@"teacher examine"); 6 } 7 8 -(void)meeting 9 { 10 NSLog(@"teacher meeting"); 11 } 12 13 -(void)travle 14 { 15 NSLog(@"teacher travle"); 16 } 17 @end
6、main.m 文件中的(实现调用)代码 如下:
1 #import <Foundation/Foundation.h> 2 #import "Teacher.h" 3 int main(int argc, const char * argv[]) { 4 @autoreleasepool { 5 HeadMaster *master=[[HeadMaster alloc]init]; 6 Teacher *xiaozhang=[[Teacher alloc]init]; 7 master.delegate=xiaozhang; 8 [master masterExamine]; 9 [master masterMeeting]; 10 [master masterTravle]; 11 } 12 return 0; 13 }