如何在iPhone中释放已声明对象的内存

时间:2013-08-26 06:40:39

标签: iphone ios objective-c memory-management

我面临小问题,

我在.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;
     }
  }

3 个答案:

答案 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];
}

...

属性的延迟初始化非常方便。基本上,如果它们被初始化,您将不再担心 - 当您使用属性访问器时,它们就是这样。