------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------
一、ARC
1.ARC原理
ARC 是OBjective-c编译器的特性,而不是运行时特性或者垃圾回收机制,ARC所做的只不过是在代码编译的时候为你自动在核实的位置插入release或者autorelease
指针分类: 关键字 __strong 强指针(默认情况下都是强指针)
关键字 __weak 弱指针
ARC机制__
1)判断是否是ARC机制
查看项目 信息 不能使用 retain release autorelease retainCount
在deallloc 中不能使用[suoer dealloc];
2)使用:正常创建对象,不用手动释放
ARC准侧判断 ,只要没有强指针指向对象,对象就会被回收
2.ARC下单对象内存管理
1) @autoreleasepool {
//在ARC下对象是释放的判断依据:对象没有强指针,对象会立即释放
//bigBen强指针(默认的都是强指针)
Car *bigBen =[[Car alloc]init];
//bigBen的指向发生了改变,对于Car对象来说没有强指针指向,所以要立即释放对象
bigBen =nil;
[bigBen run];
}
2) Car *bigBen =[Car new];
__weak Car*bwm =bigBen;
bigBen =nil;
bigBen是强指针。重新指向了其他的内容了,对于对象来说没有强zhiz
弱指针 在对象释放自动 会自己赋值nil
3.ARC下的多对象内存管理
@class Dog;
@interfance Person : NSObject
//在ARC机制下不能使用retain 应该使用 strong 或者weak
@property (nonatomic,strong) Dog*dog;
Dog *byd= [Dog new];
Person *p =[Person new];
p.dog =byd;
1)在@property (nonatomic,weak)Dog*dog
byd =nil 时 Dog对象会立即释放 应为该对象没有强指针指向了
2)在@property (nonatomic,strong)Dog*dog;
byd =nil; person没有强指针了 会释放,Dog也会释放
4.ARC下循环引用问题
@porperty (nonatomic,strong)Dog*dog;
@porperty (nanatomic,strong)Person*peron;
Dog*dog =[Dog new];
Person*person =[Person new];
person.dog ; dog.owner; 构成一个循环引用
像这样循环引用的。dog 和person 都是局部变量,从开始到他所在代码块结束
dog的指针指向person person的指针指向dog 都是强指针这样无法释放,所以这里应该在循环引用的时候一个对象用strong 一个用weak 这样就都可以释放了。
ARC下set方法内存管理 @porperty 参数
ARC中的@property
strong:用于oc对象,相当于MRC中的retain
weak : 用于oc对象 相当于MRC中的assign
assign:用于基本数据,跟MRC中的assign一样
copy:一般用于NSString,跟MAR中的copy一样
在ARC情况下解决“循环retain”的问题:@porperty 一边用strong,一边用weak
5.ARC使用注意事项
1)ARC,只要弱指针指向的对象不存在了,就直接把弱指针做清空(赋值为nil)操作。
2)__weak Person *p=[[Person alloc] init];//不合理,对象一创建出来就被释放,对象被释放掉后,ARC把指针设置为nil
3)ARC中在porperty处理不再使用retain,而是使用strong,在dealloc中不需要再[super dealloc].
@property(nonatomic,strong)Dog*dog;
//意味着生成的成员变量_dog是一个强指针,相当于以前的retain。
4)如果换成弱指针,则换成weak,不需要加_ _。
6.ARC的兼容和互换
让程序兼容ARC和非ARC部分,转变为非ARC —fno-obj-arc 转换成ARC f-objc-arc
二、Category
1.分类的概念及作用
概念: Category 有很多中翻译:分类\别类\类目(一般叫分类)
Category是oc特有的语法,其他语言没有的语言。
分类的作用
在不修饰原有的类的基础上增加新的方法
一个庞大的类可以分模块开发
一个庞大的类可以由多个人类编写,更有利与团队合作
使用分类
1.对现有类进行扩展
2.作为子类的替代手段
3.对类的方法的归类
注意:分类的命名 类名+扩展方法
2.分类声明实现
分类:一些方法的声明和实现
作用:在不修改类的源代码的前提下,给类增加新功能
声明 @interface 带扩展的类名(分类的名称)
@end
Person+base 分类文件的命名规则
实现
@implementation 带扩展的类名(分类的名称)
@end
分类中写的方法步骤 跟类没什么区别 。使用分类的方法和使用原有的对象一样
3.分类的使用注意事项
1)分类的声明中只能增加方法,不能增加成员变量 @property(可能编译器不报错,但是运行有问题)
2)分类可以访问原来类的成员变量
3)如果分类的方法和原来的类同名,优先调用分类中的方法,原来类中的方法会被忽略
4)出现多个分类方法相同的 最后编译的那个方法最先执行。
4.Category非正式协议
非正式协议
非正式协议通常定义为NSObject的类别
所谓的非正式协议类别,即凡是NSObject或其其子类Foundation框架中的
统计一个字符串中阿拉伯的数字的个数
NSString *str = @"das435fgfh";
-----代码------
#import
@interface NSString (NSStringCount)
-(void)countNumForStringt;
@end
#import "NSString+NSStringCount.h"
@implementation NSString (NSStringCount)
- (void)countNumForStringt{
int count=0;
//循环控制
for (int i=0; i='0'&&ch <='9') {
count++;
}
}
NSLog(@"%@中的数字有%d",self,count);
}
@end
#import
#import "NSString+NSStringCount.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *str1 =@"hihasd345";
[str1 countNumForStringt];
}
return 0;
}
5.分类(Category )延展
类的延展的概念:
延展类别又称为扩展 其名字尾匿名(为空)并且新添加的方法一定要予以实现。
@intreface Person ()
@end
延展是一个特殊的分类
特点;
1)可以在延展中 定义实例变量
2)不能使用@implementation 类名() 实现类别的方法
3)通过延展来实现的方法是私有的(相对的)
4)作用可以定义私有的变量方法
类别与类扩展的区别
1类别中只能增加方法
2.扩展类不仅可以增加方法,还可以增加实例变量,只是该实例变量默认是私有的类型
3.类扩展中声明的方法没被实现,编译器是会警告的,但是类别中的方法没有被实现编译器是不会有任何警告的。这个应为类扩展是在编译阶段被添加到类中的。而类别是在运行时添加到类中
4.类扩展不能像类别那样拥有独立的实现部分,也就是说,类扩展所声明的方法必须依托对应类的实现部分来实现
5.定义在.m文件中的类扩展方法为私有方法,定义在.h文件中的类扩展方法为公有。类扩展是在.m文件中申明私有方法的非常好的方式