Brief Intro to Blocks 4:Memory Management with Blocks

Memory Management with Blocks

At runtime, a block literal expression is allocated on the stack and thus has the same lifetime as a local variable. As a result, it must be copied to permanent storage (i.e., onto the heap) to be used outside of the scope in which it is defined. For example, if you want to return a block literal from a method or save it for later use, then the block must be copied onto the heap and subsequently released when no longer in use. Listing 15-15 illustrates a block literal that’s used outside its scope. This may result in a dangling pointer that causes the program to crash.

Listing 15-15.  Block Literal Used Outside of Its Lexical Scope

void (^greetingBlock)(void);
{  // scope begins, local variables pushed onto stack
  greetingBlock = ^{
    NSLog(@"Hello, World!");
  };
}  // scope ends, stack variables (e.g. the block literal) popped off stack
greetingBlock();  // Block invocation may cause the program to crash!

Listing 15-15 shows that the block literal expression assigned to the variable greetingBlock has the same lifetime as a local variable; it thus no longer exists outside of its lexical scope. Objective-C includes copy (Block_copy()) and release (Block_release()) operations that provide memory management for block literals.

The Block_copy() operation copies a block literal onto the heap. It is implemented as a function that takes a block literal reference as its parameter and returns a block reference of the same type.

The Block_release() operation releases a block literal from the heap so that its memory is reclaimed. It is implemented as a function that takes a block reference as its parameter. A block reference is released from the heap if it matches a corresponding block reference that was copied to the heap; otherwise, the function call has no effect. In order to avoid a memory leak, aBlock_copy() call must be balanced by a corresponding Block_release()The Foundation Framework defines copy and release methods for blocks that are the functional equivalent of theBlock_copy() and Block_release() functions. Listing 15-16 updates the code in Listing 15-15 with the appropriate block copy operations.

Listing 15-16.  Using the Block Copy and Release Methods

void (^greetingBlock)(void);
{
  greetingBlock = [^{
    NSLog(@"Hello, World!");
  } copy];
}
greetingBlock();          // Block invocation works (uses heap storage)
[greetingBlock release];  // released block to prevent memory leak

With ARC memory management, the compiler automatically performs the block copy and release operations as long as the block does not return an id type or pass an id type as a parameter. In either case, the copy and release operations must be performed manually, as with MRR memory management. Listing 15-17 demonstrates the use of these operations for a block that passes an idtype as a parameter.

Listing 15-17.  Using the Block_copy and Block_release Functions for Blocks with an id Type Parameter

void (^greetingBlock)(id salutation);
{
  greetingBlock = Block_copy(^(id salutation){
  NSLog(@"%@, World!", salutation);
  });
}
greetingBlock(@"Hello");
Block_release(greetingBlock);

Variables declared with the __block storage type have different semantics, depending on whether or not MRR or ARC memory management is in use. Under MRR, __block variables are not retained if used within a block literal; however, under ARC, __block variables are retained if used within a block literal. What this means is that if you are using ARC memory management and don’t want a __blockvariable to be retained (for example, to avoid circular references), the __weak storage type should also be applied to the variable.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值