arc automatic referencing counting

来源:互联网 发布:手机网络信号不稳定 编辑:程序博客网 时间:2024/05/22 12:18

ARC会得出对象需要的生命周期,在编译的时候自动插入内存管理语句。编译器还会自动生成需要的dealloc函数,而不需要手动在dealloc中添加release。

使用ARC,将不再需要使用retain, release, autorelease。

对象属性默认使用strong存储。


使用规则:

1.不能显示调用dealloc

2.不能实现或调用retain, release, retainCount, autorelease, 使用@selector(retain)等形式调用也是不行。

3.可以实现dealloc方法,但是不能调用super dealloc,也不能释放对象属性,但可以把delegate置为nil,释放Core Foundation变量。

4.可以使用CFRetain, CFRelease

5.不能使用NSAllocateObject, NSDeallocateObject, 只能用alloc,运行时会管理dealloc。

6.不要使用C结构体对象,使用Objective C类来管理数据。

7.id和void *不能随意转换,必须使用特殊的转换方法,来明确的告诉编译器对象的生命周期。Objective C和Core Foundation对象间的转换需要通过函数,以参数的方式传人,转换成需要的类型。

8.不能再使用NSAutoreleasePool, 使用@autoreleasepool block代码块代替。它比NSAutoreleasePool效率更高。

9.不能使用内存区域,memory zones。 现在不必使用NSZone, Objective C运行时会忽略NSZone。

10.不能访问以new开头的函数。所以一般不能定义new开头的属性,如果必须使用new开头,必须指定不是new开头的get函数。

@property NSString *newTitle;//不行

@property (getter=theNewTitle) NSString *newTitle;//可以


ARC引入的一些修饰符:

strong:ARC默认的对象类型。

weak:类似assign,而且当对象没有引用时,自动赋值为nil.


__strong

__weak

__unsafe_unretained:当引用的地址被释放时,访问它会很危险。

__autoreleasing:传人函数的对象参数,当函数结束时,释放。


正确的修饰对象方法:

ClassName * qualifier variableName;


MyClass * __weak myWeakReference;


使用__weak时需要小心:

NSString * __weak string = [[NSString alloc] initWithFormat:@"abc%@",@"bcd"];

NSLog(@"string:%@", string);

虽然string是alloc的,并且后面有NSLog调用,但是没有一个对string的强引用,所以,第一行就已经释放,并赋值为nil。

所以__weak修饰的对象,必须首先有强引用,才能保住对象。


但是下面的代码是可行的:

NSError *error;

BOOL OK = [myObject performOperationWithError:&error];

if(!OK){

    //能正常使用error

}

原因是编译器做了以下工作:

NSError *  __strong error;

-(BOOL) performOperationWithError:(NSError * __autoreleasing *)error;

所以最后的代码是这样的:

NSError * __strong error;

NSError * __autoreleasing tmp = error;

BOOK OK = [myObject performOperationWithError:&tmp];

error = tmp;

if(!OK){

//...

}


ARC block代码块怎么避免循环引用:

MyViewController *myController = [[MyViewController alloc] init];

// ...

myController.completionHandler = ^(NSInteger result) {

[myController dismissViewControllerAnimated:YES completion:nil];

};

[self presentViewController:myController animated:YES completion:^{

[myController release];

}];


处理方法:

1.使用__block,并且在block中把myController赋值为nil.

MyViewController * __block myController = [[MyViewController alloc] init];

// ...

myController.completionHandler = ^(NSInteger result) {

[myController dismissViewControllerAnimated:YES completion:nil];

myController = nil;

}

2.使用__weak

MyViewController *myController = [[MyViewController alloc] init...];

// ...

MyViewController * __weak weakMyViewController = myController;

myController.completionHandler = ^(NSInteger result) {

[weakMyViewController dismissViewControllerAnimated:YES completion:nil];

}

更好的方法:

MyViewController *myController = [[MyViewController alloc] init...];

// ...

MyViewController * __weak weakMyController = myController;

myController.completionHandler = ^(NSInteger result){

MyViewController *strongMyController = weakMyController;

if(strongMyController){

// ...

[strongMyController dismissViewControllerAnimated:YES completion:nil];

// ...

}

else {

// Probably nothing...

}

};


堆栈变量被初始赋值为nil

- (void) myMethod {

  NSString *name;

NSLog(@"name: %@", name);

}


-fobjc-arc/ -fno-objc-arc



0 0
原创粉丝点击