您的位置:首页 > 移动开发 > IOS开发

iOS 在 ARC 环境下 dealloc 的使用、理解误区

2016-02-22 15:05 465 查看
在 ARC 环境下,重载的 dealloc 方法一样会被调用,只不过,不能在该方法的实现中调用父类的该方法。

下面看个示例来验证一下:

一个待测试的类 Test,创建和销毁它,在 ARC 环境下看看 dealloc 是否被调用了;第二就是在 dealloc 中调用父类的实现,看看会怎样。

另一个是视图控制器,用于添加两个按钮,其中一个按钮的事件方法用于创建 Test 类,另一个用于释放,这里同样测试了一个 ARC 中当一个对象被 0 个引用指向时,是否马上释放。

Test 类的声明如下:

#import

@interface Test : NSObject

@end


Test 类的声明和实现如下:
#import "Test.h"

@implementation Test

- (id)init {

self = [super init];
if (self) {

}
return self;
}

- (void)dealloc {

NSLog(@"dealloc");
//[super dealloc];
}

@end


视图控制器声明:

#import
#import "Test.h"

@interface ViewController : UIViewController

@property (nonatomic, strong) Test *test;

@end


视图控制器实现:

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}

- (IBAction)generateButtonPressed:(UIButton *)sender {

self.test = [[Test alloc] init];
}

- (IBAction)removeButtonPressed:(UIButton *)sender {

self.test = nil;//调用dealloc是将self.a指向的内存块的ref count减一  当ref count为0时系统回收此内存块,大于0则不回收
}

@end


显示的结果:

2016-02-22 14:44:54.644 cest[17758:132085]
创建

2016-02-22 14:44:56.233 cest[17758:132085]
走了自己的dealloc方法

2016-02-22 14:44:56.233 cest[17758:132085]
释放

经测试,一切正常,而且在按释放按钮时,Test 类的对象的 dealloc 方法会立即被调用,基本没有感觉到延迟。

另外,当在 Test 类的 dealloc 方法最后调用父类的 dealloc 方法实现时,XCode 5.1.1 会自动出现提示,如下图:

ARC 拒绝 显式 ‘dealloc’ 消息发送。



讨论

该对象的后续消息会生成一个错误信息,该信息指出消息发送给了一个已释放的对象(提供了未被重用的已释放内存)。

Subsequent messages to the receiver may generate an error indicating that a message was sent to a deallocated object (provided the deallocated memory hasn’t been reused yet).

你重载该方法用于处理资源,而不是用于处理对象的实例变量,例如:

You override this method to dispose of resources other than the object’s instance variables, for example:
- (void)dealloc {
free(myBigBlockOfMemory);


在 dealloc 的实现中,不要调用父类的实现。你应该尽量避勉使用 dealloc 管理有限资源诸如文件描述符的生命周期。

In an implementation of dealloc, do not invoke the superclass’s implementation. You should try to avoid managing the lifetime of limited resources such as file descriptors usingdealloc.

决不要直接发送 dealloc 消息。相反,任何对象的 dealloc 方法由运行时调用。参看 高级内存管理编程指南 以获得更详细的内容。

You never send a dealloc message directly. Instead, an object’sdealloc method is invoked by the runtime. See Advanced Memory Management Programming Guide for more details.

特别注意事项

Special Considerations


当未使用 ARC 时,你的 dealloc 实现必须把调用父类的实现作为最后一条指令。(隐含的意思就是,使用 ARC 时不能调用父类的实现)

When not using ARC, your implementation of dealloc must invoke the superclass’s implementation as its last instruction.

在ARC下,CoreFoundation存在的意义

你需要释放一些不在 ARC 控制下的资源。 例如 Core Foundation 对象中调用 CFRelease(), 对那些通过 malloc() 分配的内存调用 free(), 注销通知,停止 Tiner, 等等。

如果你是一个对象的代理的话,有时必须显式的断开和它的连接,但通常这都是自动的。 大部分情况下,代理都是弱引用, 当一个即将被释放的对象是其他对象的代理的话, 当这个对象被销毁时,代理指针将会被自动设置为 nil。 弱指针在这之后会被自动清楚。

另外, 在你的 dealloc 方法中, 你仍然可以使用实例变量, 因为他们在这时候还没被释放掉。 在 dealloc 返回之前,都不会被释放。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: