在哪里发布__block变量?

时间:2014-01-17 14:39:46

标签: ios objective-c

我有以下代码段:

-(void) doSomething
{
    __block NSMutableArray *objArray = [[NSMutableArray alloc] initWithCapacity:0];
      [self performOperationWithBlock:^(void)
      {
         //adding objects to objArray
         .
         .
         //operation with objArray finished

         // 1. should objArray be released here?
      }];

      //2. should objArray be released here?
}

我应该自动发布objArray吗?

4 个答案:

答案 0 :(得分:5)

如果是异步调用,在实际块中创建NSMutableArray是有意义的:

  [self performOperationWithBlock:^(void)
  {
     NSMutableArray *objArray = [[NSMutableArray alloc] initWithCapacity:0];

     //adding objects to objArray
     .
     .
     //operation with objArray finished

     // 1. should objArray be released here?
  }];

因为在块之后你不需要它(它只对异步操作的持续时间有意义),所以最后在你使用它之后释放它。或者,你可以简单地说:

     NSMutableArray *objArray = [NSMutableArray array];

在这种情况下,您无需释放它。

如果是同步通话,您应该在阻止之后release


注意:我假设您在使用块之前填充NSMutableArray,这意味着在块启动之前创建它是有意义的。

异步方法:

-(void) doSomething
{
   // Remove the `__block` qualifier, you want the block to `retain` it so it
   // can live after the `doSomething` method is destroyed
    NSMutableArray *objArray = // created with something useful

    [self performOperationWithBlock:^(void)
     {
       // You do something with the objArray, like adding new stuff to it (you are modyfing it).
       // Since you have the __block qualifier (in non-ARC it has a different meaning, than in ARC)
       // Finally, you need to be a good citizen and release it.
     }];

    // By the the time reaches this point, the block might haven been, or not executed (it's an async call).
    // With this in mind, you cannot just release the array. So you release it inside the block
    // when the work is done
}

同步方法

它假定您需要立即获得结果,并且在块执行后进一步使用Array时有意义,所以:

-(void) doSomething
{
   // Keep `__block` keyword, you don't want the block to `retain` as you
   // will release it after
    __block NSMutableArray *objArray = // created with something useful

    [self performOperationWithBlock:^(void)
     {
         // You do something with the objArray, like adding new stuff to it (you are modyfing it).
     }];
    // Since it's a sync call, when you reach this point, the block has been executed and you are sure
    // that at least you won't be doing anything else inside the block with Array, so it's safe to release it

    // Do something else with the array

    // Finally release it:

    [objArray release];
}

答案 1 :(得分:1)

如果方法是 synchronous (即在与调用线程相同的线程上工作),你应该在performOperationWithBlock:方法完成后释放它。(/ p) >

如果该方法是异步,那么它应该在块中释放。

答案 2 :(得分:0)

如果您不使用ARC,则应在不再需要时释放阵列。根据您添加的评论并假设doSomething方法对块外部的数组没有任何作用,它应该在您的1.标记处。

答案 3 :(得分:0)

选项2.在[self performOperationWithBlock:...]后发布。 Block将自己保留并释放你的objArray。释放内部块是危险的:块可以执行两次然后objArray将被释放两次,但它应该释放一次。所以只剩下一个选项:2。