首先ARC是什么?
iOS5中引入了自动引用技数(Automatic Reference Counting)也就是我们所说的ARC。如果说开启了自动引用计数也就是ARC那么编译器就会在你的程序中恰当的位置,插入retain,release和autorelease。也就是说我们不需要去为内存管理而操心。
非ARC的工作原理
再没有ARC的时候我们需要手动去管理内存,基本的工作方式有俩点:
1)如果你需要持有一个对象的话,你就需要保留(retain)它,除非它已经被你保留。
2)如果你不在持有一个对象的话,你就需要释放(release)它,除非它已经被你释放(使用autorelease)。
作为一个刚入门的iOS小白手动管理内存的原则并不难,但是却很容易犯错。要么你将对象释放了太多次。你的变量指向了不在有效的数据,从而导致程序崩溃;要么因为你没有充分释放对象,并让它们永远存在下去,而导致内存耗尽。
而在使用ARC以后,我们就不需要这么做了。甚至连release都不需要。下面来看俩段代码。
@interface MyARCObject : NSObject {
NSString *name;
}
-(id)initWithName:(NSString *) newName;
@end
@implementation MyARCObject
-(id)initWithName:(NSString *)newName {
self = [super init];
if (self) {
name = [newName retain];
}
return self;
}
-(void)dealloc {
[name release];
[Super dealloc];
}
@end
这是没有使用ARC之前下一段是引用了ARC的代码
@interface MyARCObject : NSObject {
NSString *name;
}
-(id)initWithName:(NSString *)newName;
@end
@implementation MyARCObject
-(id)initWithName:(NSString *)newName {
self = [super init];
if (self) {
name = newName;
}
return self;
}
@end
由此可以看出在使用ARC后我们的代码变的简洁不少。那么使用ARC有什么好处呢?
- 首先我们不需要去考虑繁琐的内存管理,ARC会自动为我们插入retain,release,autorelease;
- 代码的总量减少了,整体看着清爽。
- 代码高速化,由于编译器管理引用技数,减少了低效代码的可能性。
Objective_C中的对象
以前手动管理内存的时候,必须保留一个对象来让它存在。有了ARC以后这不在是必要的。你要做的只是创建一个对象的指针。当指针得到一个新值或者不在存在的时候,相关的对象会被释放。这对于所有的变量都适用:成员变量,同步属性,甚至是局部变量。总结来说有两点:
- 当对象的持有者存在,那么就可以使用该对象。
- 当对象的持有者不存在,那么该对象就被抛弃。
那么如何确定持有者呢?下面来看段代码:
self.textField.text = @"Jack"; //textField为文本框
NSString *firstName = self.textField.text;
firstName变量成为了指向文本框内容中NSString对象的指针。firstName变量现在是这么string对象的持有者。一个对象可以有多个持有者。在用户改变UITextField的内容之前,它的text属性同样是这个string对象的所有者。这样就有俩个指针保持同一个对象的存在。
过一会,用户又向文本框中输入了新的文字:"Rose" 于是文本框中的text属性现在指向了一个新的string对象。原来的string对象“Jack”仍然有一个持有者(firstName变量)因此存在于内存中。
只有当firstName也得到一个新值,或者超出存在范围(可能是局部变量而方法结束了),或者它是成员变量而它所属的对象已经被释放。所有权才会过期对象不再有持有者,它的保留计数降至0从而使该对象被释放。
我们把firstName=跟textField这类指针称为强指针也就是“strong” ,因为他们保持了对象的存在默认情况下。成员变量,和局部变量都是强指针。
同样也存在弱指针“weak”,弱指针变量仍然可以指向对象但是不在成为所有者:
self.textField.text = @"Jack";
__weak NSString *weakName = self.textField.text;
weakName指针变量指向textField.text属性相同的string对象,但不在有所有者。如果文本框的内容改编,该NSString对象将不再有持有者,所以被释放了。放着发生改变weakName的值自动被置为nil。即所谓的“归零”弱指针。
- __strong变量缺省都带有__strong关键字。如果变量什么都不写那么默认就是强引用。
- __weak这是弱引用关键字。这是新特性在iOS5开始导入如果没有那么就是出现刚创建酒杯释放的问题:
__weak NSString *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]]; NSLog(@"string: %@", string); //此时 string为空
- __unsafe_unretained 这也是弱参照。区别是是否执行string = nil;(注意这是自动添加的,不是手写)__autoreleasing
- __autorelesing 该关键字使对象延迟释放。比如你想传一个未初始化的对象引用到一个方法当中,在此方法中实例化此对象,那么这种情况可以使用__autoreleasing.