如何发布NSMutableArray?

时间:2012-08-15 19:43:51

标签: iphone ios ios5 nsmutablearray

我有一个带有以下属性的NSMutableArray:

@property (nonatomic, strong) NSMutableArray *alarmTableArray;

alarmTableArray = [[NSMutableArray alloc]init];
FMDBDatabaseAccess *db = [[FMDBDatabaseAccess alloc] init];
alarmTableArray = [db getAlarm];

我尝试发布此阵列,但我最终得到了EXC_BAD_ACCESS 我真的很担心这个。

如何发布此阵列?

3 个答案:

答案 0 :(得分:2)

您使用的是“强”的描述符,这是一个ARC术语。这应该保留,如果你只是将属性设置为nil,它将自动释放它。您应该在viewDidUnload中将其设置为nil,因为ViewWillDissappear仅表示您的viewcontroller正在保持可见性而不是它正在被销毁。

答案 1 :(得分:1)

更新答案

我想我知道你在做什么。您希望从SQL中获取一系列行,并将其存储在一个数组中。

从SQL获取数据行并存储到类实例变量数组中的一种技术是不返回临时数组,而是将类实例变量数组作为引用传递给方法并直接修改数组。

所以代替这个伪代码

-(NSMutableArray *)doSomething
{
   NSMutableArray *tempArray;

   while (DB select statement has found rows)
   {
       CockTail *objCT = [[CockTail alloc] init];

       objCT.name = @"...";
       objCT.price = @"...";

       [tempArray addObject:objCT];

       [objCT release];
   }

   return [tempArray autorelease];
}

// class instance variable array
instanceVarArray = [[NSMutableArray alloc] init];
instanceVarArray = [self doSomething]; // here is where you confusion arise

你可以这样做:

-(void)doSomething:(NSMutableArray *)paramArray
{
    // remove previously fetched data
    [paramArray removeAllObjects];

    SQL select statement

    while(has rows)
    {
        CockTail *objCT = [[CockTail alloc] init];

        objCT.name = @"...";
        objCT.price = @"...";

        // NOTE: we are directly modifying our class instance variable array
        // here since it was passed by reference :D
        // and so there is no need to worry about releasing the array
        [paramArray addObject:objCT];

        [objCT release];
    }
}

// Now all you do is pass in your class instance variable array
instanceVarArray = [[NSMutableArray alloc] init];
[self doSomething:instanceVarArray];

原始答案

嗯,也许我错了,但是当你从FMDBDatabaseAccess分配一些数据时,你不是在这里扔掉第一行的“alloc init”:

// LINE 1: this instance of NSMutableArray here is allocated
alarmTableArray = [[NSMutableArray alloc]init];

// LINE 2
FMDBDatabaseAccess *db = [[FMDBDatabaseAccess alloc] init];

// LINE 3:this line here essential breaks the pointer link point to the NSMutableArray instance on line 1 
alarmTableArray = [db getAlarm];

现在除非你做

// LINE 4
[alarmTableArray retain];

否则,你的alarmTableArray从未被分配(因为你覆盖了指针链接)。结果,您的探查器告诉您,导致内存泄漏。

立即执行发布将为您提供EXEC_BAD_ACCESS

我认为你想做的是:

alarmTableArray = [[NSMutableArray alloc]init];
FMDBDatabaseAccess *db = [[FMDBDatabaseAccess alloc] init];

// this now uses the setter method (mutator method generated by @property) to do the copy
self.alarmTableArray = [db getAlarm];

答案 2 :(得分:0)

看看你的while循环,我不得不问你为什么要发布一个局部范围变量?

 CockTail *cocktailValues = [[CockTail alloc] init];
 ...

 [cocktails addObject:cocktailValues];
 [cocktailValues release];

上面每行代码的细分:

  1. 当您分配并初始化CockTail对象时,释放/保留计数为0。
  2. 将对象添加到NSMutableArray会将释放/保留计数增加到1.
  3. 将CockTail对象添加到阵列后释放它会将释放/保留计数减少回0。
  4. 因此,稍后当您释放NSMutableArray或尝试访问其中的对象时,对象已经消失。

    记住头号规则,只发布你保留的内容。