一,ARC的概念和原理:
1,指针分类:
(1)强指针:默认的情况下,所有的指针都是强指针,关键字strong;
(2)弱指针:_ _weak关键字修饰的指针;
2,什么是ARC:
Automatic Reference Counting,自动引用计数,即ARC;
ARC是新的LLVM 3.0编译器的一项特性;
3,ARC原理:
ARC是Objective-C编译器的特性,而不是运行时特性或者垃圾回收机制,ARC所做的只不过是在代码编译时为你自动在合适的位置插入release或autorelease,retain。
4,ARC判断准则:
(1),只要还有一个强指针变量指向对象,对象就会保存在内存中。
(2),只要没有强指针指向对象,对象就会被释放。
5,ARC下循环引用问题:
一端使用strong,一端使用week;
二,ARC下@property参数
ARC中的@property
strong: 用于OC对象, 相当于MRC中的retain;
weak: 用于OC对象,释放了之后,会将指针置为nil, 其他相当于MRC中的assign;
assign: 用于基本数据类型, 跟MRC中的assign一样;
copy: 一般用于NSString, 跟MRC中的copy一样;
三,ARC使用特点和注意事项:
1、ARC特点总结
(1)不允许调用release,retain,retainCount;
(2)允许重写dealloc,但是不允许调用[super dealloc];
(3)@property的参数:
strong: 相当于原来的retain(适用于OC对象类型),成员变量是强指针
weak: 相当于原来的assign,(适用于oc对象类型),成员变量是弱指针
assign: 适用于非OC对象类型(基础类型)
copy: 一般用于NSString, 跟MRC中的copy一样
2、ARC使用注意事项
1)ARC中,只要弱指针指向的对象不在了,就直接把弱指针做清空(赋值为nil)操作。
2)__weak Person *p=[[Person alloc] init];//不合理,对象一创建出来就被释放掉,对象释放掉后,ARC把指针设 置为nil。
3)ARC中在property处不再使用retain,而是使用strong;
@property(nonatomic,strong)Dog *dog;
// 意味着生成的成员变量_dog是一个强指针,相当于以前的retain。
四,ARC和MRC之间互相转换:
1,将MRC工程转为ARC工程:
用XCode工具: Edit -> Convert -> To Objective-C ARC
2,ARC和MRC之间互转的指令:
ARC转变为MRC指令, -fno-objc-arc
MRC转变为ARC的指令, -f-objc-arc
#pragma mark Dog.h
#import
@interface Dog : NSObject
+(Dog*)dog;
-(void)run;
@end
#pragma mark Dog.m
#import "Dog.h"
@implementation Dog
+(Dog*)dog{
return[Dognew];
}
-(void)run{
NSLog(@"狗以200码速度撞树上了");
}
- (void)dealloc{
NSLog(@"Dog dealloc");
// [super dealloc];
}
@end
#
pragma mark
main.m
#import
#import "Dog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//ARC机制下对象的释放
Dog *jd = [Dog dog];
[jd run];
}
return 0;
}
ARC下单个对象内存管理
#pragma mark Car.h
#import
@interface Car : NSObject
-(void)run;
@end
#pragma mark Car.m
#import "Car.h"
@implementation Car
-(void)run{
NSLog(@"车在疯跑");
}
- (void)dealloc
{
NSLog(@"Car dealloc");
}
@end
#pragma mark main.m
#import
#import "Car.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//在ARC下对象释放的判断依据:对象没有强指针指向
//对象会立即释放内存空间
// bigBen 强指针(指针默认的都是强指针)
Car *bigBen = [Car new];
//定义另外一个强指针指向
//__strong 修饰符,修饰这个指针是一个强指针,也可以不写
//__weak 修饰的这个指针是若指针
//__strong Car *bmw = bigBen;
__weak Car *bwm2 = bigBen;
NSLog(@"bigBen = %@,bwm2 = %@",bigBen,bwm2);
//bigBen的指向发生改变,对于Car对象来说没有强指针指向了,所以要释放对象
bigBen = nil; //
// 要 1) bigBen 是强指针,重新指向其他内容了,对于对象来说没有强指针了
// 2) 弱指针 赋值为nil
NSLog(@"bigBen = %@,bwm2 = %@",bigBen,bwm2);
[bwm2 run]; //[nil run];
[bigBen run]; //[nil run];
NSLog(@"xxxxxx");
}
return 0;
}
ARC多对象内存管理
#pragma mark Dog.h
#import
@interface Dog : NSObject
@end
#pragma mark Dog.m
#import "Dog.h"
@implementation Dog
- (void)dealloc{
NSLog(@"Dog dealloc");
}
@end
#pragma mark main.m
#import
#import "Dog.h"
#import "Person.h"
intmain(intargc, constchar* argv[]) {
@autoreleasepool {
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 // Dog对象不会被立即释放
// byd = nil;
}
return 0;
}
#pragma mark Person.h
#import
//#import "Dog.h"
@class Dog;
@interface Person : NSObject
// 在 ARC机制下,不能使用retain
// 应该使用strong
// weak
@property (nonatomic,strong) Dog *dog;
@end
#
pragma mark
Person.m
#import "Person.h"
@implementation Person
- (void)dealloc{
NSLog(@"Person dealloc");
}
@end