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

3

我遇到了一个小问题,

我在.h文件中声明了一个数组,并在viewDidLoad方法中分配了它。在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个回答

3
dealloc方法的结尾添加[super dealloc];,而不是在开头。这是苹果在其dealloc方法的文档中推荐的做法
引用如下:

当不使用ARC时,您的dealloc实现必须调用超类的实现作为其最后一条指令。

请按以下方式修改您的代码:
   -(void)dealloc
   {
      if (objArray!=nil)
     {
         [objArray removeAllObjects];
         [objArray release];objArray=nil;
     }
      [super dealloc];
   }

此外,当您释放整个数组时,无需调用[objArray removeAllObjects]。当数组被释放时,它会在内部调用release来释放所有包含的对象。
希望这有所帮助!

1

[super dealloc]方法必须在此方法的结尾处调用。因为当您调用[super dealloc]时,无法再访问超类的变量,因为它们已被释放。在最后一行调用超类始终是安全的。

-(void)dealloc
   {

// ----------- your stuff ------------

      [super dealloc];

  }

谢谢您,Dharmir Choudary。 - Ravi

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是否不为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];
}

...

属性的延迟初始化非常方便。基本上,当您使用属性访问器时,您不必再担心它们是否已经被初始化 - 它们只是已经被初始化了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接