我面临小问题,
我在.h文件中声明一个数组,并在viewDodLoad
方法中分配它。在dealloc
方法中,我检查数组是否不等于nil
,然后array=nil
。但它在iOS 5.1.1中崩溃了。我无法理解这次事故的原因。
我的代码,
@interface SampleApp : UIViewController
{
NSMutableArray *objArray;
}
@end
@implementation SampleApp
- (void)viewDidLoad
{
[super viewDidLoad];
objArray=[[NSMutableArray alloc]init];
}
-(void)dealloc
{
[super dealloc];
if (objArray!=nil)
{
[objArray removeAllObjects];
[objArray release];objArray=nil;
}
}
答案 0 :(得分:3)
在[super dealloc];
方法的末尾添加dealloc
,而不是在开头。 Apple推荐documentation for dealloc
method。
当不使用ARC时,dealloc的实现必须调用超类的实现作为其最后一条指令。
修改您的代码,如下所示
-(void)dealloc
{
if (objArray!=nil)
{
[objArray removeAllObjects];
[objArray release];objArray=nil;
}
[super dealloc];
}
此外,在释放整个阵列时,无需调用[objArray removeAllObjects]
。当数组被释放时,它将在内部调用所有包含的对象上的release
。
希望有所帮助!
答案 1 :(得分:1)
[super dealloc] 方法。因为您不能再访问超类的变量,因为它们在您调用[super dealloc]时会被释放。在最后一行调用超类总是安全的。
-(void)dealloc
{
// ----------- your stuff ------------
[super dealloc];
}
答案 2 :(得分:0)
使用手动内存管理,您的-dealloc方法如下所示:
-(void)dealloc
{
[objArray release]; // objArray *may* be nil, and this is
// sufficient to release all elements as well.
// call super at the end
[super dealloc];
}
此外,您的方法-viewDidLoad
中可能存在内存泄漏。如果你像你的例子那样做:
- (void)viewDidLoad
{
[super viewDidLoad];
objArray=[[NSMutableArray alloc]init];
}
即使objArray
已拥有有效对象,可能分配objArray
新指针。新指针值将简单地覆盖旧指针,因此您无法再释放旧指针。
一种方法是检查objArray
是否不是nil
,然后在为其分配新值之前将其释放:
- (void)viewDidLoad
{
[super viewDidLoad];
if (objArray) {
[objArray release], objArray = nil;
}
objArray = [[NSMutableArray alloc]init];
}
然而,更好的方法是采用“延迟初始化属性”:
首先,为您的数组定义“内部属性”(除非您希望数组可公开访问)。在您的.m文件中:
// In your implementation file define a private property in a class extension:
@interface SampleApp ()
@property (nonatomic) NSMutableArray* objArray;
@end
@implementation SampleApp
@synthesize objArray = _objArray; // this will create the setter
-(void)dealloc
{
[_objArray release];
[super dealloc];
}
// Lazy init property: (this is the getter)
- (NSMutableArray*) objArray {
if (_objArray == nil) {
_objArray = [[NSMutableArray alloc] init];
}
return _objArray;
}
- (void) viewDidLoad {
[super viewDidLoad];
// When needing the array, simply *and always* access it
// through the property "self.objArray":
NSUInteger count = [self.objArray count];
}
...
属性的延迟初始化非常方便。基本上,如果它们被初始化,您将不再担心 - 当您使用属性访问器时,它们就是这样。