您的位置:首页 > Web前端

Automatic Reference Counting (ARC) 自动引用计数

2015-07-23 08:20 423 查看
http://blog.csdn.net/nokiaxjw/article/details/8104592http://developer.apple.com/library/mac/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.htmlAutomaticReferenceCounting(ARC)是一个编译器的功能,提供了对Objective-C对象的自动内存管理。ARC在编译期间自动在适当的地方添加Objective-C对象的retain和release操作代码。一.总结ARC在编译期间,根据Objective-C对象的存活周期,在适当的位置添加retain和release代码。从概念上讲,ARC与手动引用计数内存管理遵循同样的内存管理规则。ARC也无法防止strong引用循环。ARC还引入了新的修饰符来修饰变量和声明属性。变量的修饰符__strong,__weak,__unsafe_unretained,__autoreleasing,默认是_strong;声明属性的修饰符strong,weak,unsafe_unretained,默认是strong。Objective-C对象和CoreFoundation-style对象直接的转换。你需要显示地告诉编译器转换后对象的所有权,转换修饰符号:__bridge,
__bridge_retained
CFBridgingRetain,__bridge_transfer
或[code]CFBridgingRelease
ARC支持的系统:Xcode4.2forOSXv10.6和v10.7(64位应用程序)iOS4iOS5。weak不支持OSXv10.6和iOS4。
Xcode提供一个把手动引用计数转换成ARC的工具,chooseEdit>Refactor>ConverttoObjective-CARC。二.ARC概述你不需记住什么时候要用retain,release,andautorelease,ARC评估你的对象的生命周期,并在编译时自动插入适当的内存管理。编译器还为你生成相应的dealloc方法。一个Person类声明如下:
@interfacePerson:NSObject
@propertyNSString*firstName;
@propertyNSString*lastName;
@propertyNSNumber*yearOfBirth;
@propertyPerson*spouse;
@end
@implementationPerson
@end
属性的默认修饰符是strong。一个contrived方法如下:
-(void)contrived{
Person*aPerson=[[Personalloc]init];
[aPersonsetFirstName:@"William"];
[aPersonsetLastName:@"Dudney"];
[aPersonsetYearOfBirth:[[NSNumberalloc]initWithInteger:2011]];
NSLog(@"aPerson:%@",aPerson);
}
ARC负责aPerson和NSNumber对象的内存释放。三.ARC强制执行新规则1.不能显示调用dealloc([superdealloc]),执行或调用retain,release,retainCount,orautorelease;禁止使用选择器@selector(retain),@selector(release),等。你可以实现一个dealloc方法,来释放实例变量以外的资源,例如:系统类调用[systemClassInstancesetDelegate:nil]和未使用ARC编译的代码。在dealloc方法中,ARC在适当的地方添加release来负责释放实例变量。2.不能使用
NSAllocateObject
NSDeallocateObject类。
3.不能在C结构体中使用对象指针。使用Objective-C类代替C结构体。
4.id和void*之间要求显示转换。
使用__bridge,__bridge_retained或CFBridgingRetain,__bridge_transfer或CFBridgingRelease来显示转换。
5.用
@autoreleasepool{}代替NSAutoReleasePool。
6.不能使用memoryzones。不再需要NSZone。7.实例变量的访问名称不能用new作为前缀,不能声明一个属性用new作为前缀。
@propertyNSString*newTitle;//错误
@property(getter=theNewTitle)NSString*newTitle;//修改访问方法,正确
四.ARC推出新的对象生命周期修饰符1.属性声明修饰符:strong,weak,unsafe_unretained,默认strongstrong和retain相似,只要有一个strong指针指向对象,该对象就不会被销毁;(一个对象,要是没有任何一个strong引用指向该对象,将马上被销毁);weak,声明为weak的指针,weak指针指向的对象一旦被释放,weak的指针都将被赋值为nil;unsafe_unretained,用unsafe_unretained声明的指针,指针指向的对象一旦被释放,这些指针将成为野指针。
//以下2行代码执行效果一样
@property(retain)MyClass*myObject;
@property(strong)MyClass*myObject;
//Thefollowingdeclarationissimilarto"@property(assign)MyClass*myObject;"
//exceptthatiftheMyClassinstanceisdeallocated,
//thepropertyvalueissettonilinsteadofremainingasadanglingpointer.
@property(weak)MyClass*myObject;
//声明unsafe_unretained属性
@property(nonatomic,strong)NSString*string1;
@property(nonatomic,unsafe_unretained)NSString*string2;
//执行如下代码后,self.string2成了野指针
self.string1=[[NSStringalloc]initWithUTF8String:"string1"];
self.string2=self.string1;
self.string1=nil;
NSLog(@"String2=%@",self.string2);
为了避免strong(强引用)循环,parent对象strong(强引用)child对象,child对象weak(弱引用)parent对象。2.变量的修饰符__strong,__weak,__unsafe_unretained,__autoreleasing,默认是_strong__strong:强引用,只要有一个strong引用指向该对象,那么该对象就不会被销毁;__weak:弱引用,不能保持一个对象的存活期,当弱引用指向的对象没有强引用指向时,该弱引用指针被置为nil;__unsafe_unretained,跟__weak相似,只是该引用指针成为野指针。__autoreleasing,修饰传递给方法的参数引用(id*),方法返回时自动释放。a)变量定义格式如下:
ClassName*qualifiervariableName;
MyClass*__strongmyStrongReference;//__strong是默认修饰符,等价于MyClass*myStrongReference;
MyClass*__weakmyWeakReference;
MyClass*__unsafe_unretainedmyUnsafeReference;
//string用NSString对象引用初始化后,由于没有strong引用指向该NSString对象,NSString对象马上就被释放,string被置为nil;
NSString*__weakstring=[[NSStringalloc]initWithFormat:@"FirstName:%@",[selffirstName]];
NSLog(@"string:%@",string);//输出null
b)__autoreleasing,方法的参数是个引用指针(id*):参数是个__autoreleasing的方法声明如下:
-(BOOL)performOperationWithError:(NSError*__autoreleasing*)error;
NSError*error;//或定义成NSError*_autoreleasingerror;
BOOLOK=[myObjectperformOperationWithError:&error];
if(!OK){
//Reporttheerror.
//...
//编译器自动添加了临时__autoreleasing变量
NSError*__strongerror;
NSError*__autoreleasingtmp=error;
BOOLOK=[myObjectperformOperationWithError:&tmp];
error=tmp;
if(!OK){
//Reporttheerror.
//...
//返回_autoreleasing定义的变量-(NSString*)name{_autoreleasingNSString*str=[[NSStringalloc]initWithString:@"name"];returnname;}五.ARC编译模式下,iOS和MacOSX平台对Outlets(用户接口变量)的管理统一了strong:Nib文件所有者(File'sOwner)的顶层对象(top-levelobjects);weak:视图或其他窗口中的Outlets(用户接口变量);六.ARC编译模式下,堆栈变量初始化为nil。七.使用编译器标志启用和禁用ARC-fobjc-arc启用ARC-fno-objc-arc禁用ARCa)ARC编译选项项目文件的[BuildSettings]->[AppleLLVMcompiler4.1-Language]b)在ARC编译模式下,某些源文件禁用ARC八.Corefundationstyle对象与Objective-C对象的桥接转换(Toll-Freebridge)ARC不自动负责CoreFoundation-style对象(例如
CFArrayRef
CFMutableDictionaryRef、
CGColorSpaceRef、
CGGradientRef
)的内存释放,你必须使用
CFRetain
and
CFRelease管理
CoreFoundation-style对象。Objective-C对象和CoreFoundation-style对象的转换,你需要显式告诉编译器转换后的对象的所有权。a)__bridge,只做类型转换,但是不修改对象(内存)管理权;b)
__bridge_retained或
CFBridgingRetain,将Objective-C的对象转换为CoreFoundation的对象,同时将对象(内存)的管理权交给我们,后续需要使用CFRelease或者相关方法来释放对象;
c)__bridge_transfer
CFBridgingRelease
,将CoreFoundation的对象转换为Objective-C的对象,同时将对象(内存)的管理权交给ARC。
九.手动转换项目支持ARCa)不能调用
retain
,
release
,
autorelease
.方法;b)不能调用dealloc方法;例如:[superdealloc];c)用@autorelesepool{}代替NSAutoreleasePool;d)init初始化方法,
[superinit]
改成
self=[super
init];
[superinit];//错误
self=[superinit];//正确
if(self){
...
e)没有使用ARC,类的实例变量默认是assign,对象赋值给实例变量,不会改变对象的引用计数;使用ARC后,类的实例变量默认是strong,对象赋值给实例变量,会延长对象的存活周期。
f)不能在C结构体中使用strongid;
structX{idx;floaty;};//错误
g)id和void*(includingCoreFoundationtypes)之间不能直接相互转换;h)Nib中的非顶层对象Outlets(用户接口变量),修饰符assign改为weak;顶层对象Outlets,修饰符retain改为strong。十.其他
a)__weak
不支持这些类的对象
:
NSATSTypesetter
,
NSColorSpace
,
NSFont
,
NSMenuView
,
NSParagraphStyle
,
NSSimpleHorizontalTypesetter
,and
NSTextView
b)ARC不支持管理的内容:
malloc
/
free分配的对象
,CoreFoundation-style对象,filedescriptors。CoreFoundation-style对象,它是由C的struct定义的各种对象,主要来自于CoreFoundation框架(如CFArray或者CFMutableDictionaryRef类型),或者其它采用CoreFoundation命名规范的框架,如CoreGraphics(如,CGColorSpaceRef和CGGradientRef)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: