Memory management in block

Memory management in block


Blockの具体的な使い方は

を参考してください。


Blockの使うのは二つ形式があります。

    • copyしてない。
    • copyしてます。

copyしてない場合

この場合、blockのmemory spaceはstackにいます。何の変数でも使えます。memory leakを気にしない。

typedef void (^MyBlock)(void);

// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"

// HelloWorldLayer
@interface
IntroLayer : CCLayer
{
}
@property
(nonatomic, assign) MyBlock      nocopiedBlock;
@property
(nonatomic, copy) NSString *      name;
@property
(nonatomic, assign) int               num;

@end


@implementation
IntroLayer

-(void) onEnter
{
   
[super onEnter];

   
int localVar = 10;

   
self.nocopiedBlock =  ^(void){
       
self.name = @"wang";
       
self.num = localVar + 100;
   
};

   
[self scheduleOnce:@selector(makeTransition:) delay:1];
}

-(void) makeTransition:(ccTime)dt
{
   
self.nocopiedBlock();
}
@end

ここはnocopiedBlockをassignにsetして、copyしてない。self.nocopiedBlockはonEnter scopeの全部変数を呼ばれます。self.nocopiedBlockの自身もonEnter scopeにあります。一旦onEnter以外の位置から(例えばmakeTransitionから)self.nocopiedBlockを呼んだら、落ちます。



copyしてる場合

この場合、blockのmemory spaceはstackからheapにcopyしました。memory leakを気にします。

  • local変数
    • local変数にcopyするので、blockに変更したら、stackにの元の変数と関係ないです。
  • static/global変数
    • heapにcopyしない、read/writeも出来る。
  • objective c対象
    • selfの変数を呼ばれたら、selfをretainされます。selfにこのblockをcopyしたので、循環参照があります。

解決方法は、

__block ClassName *selfInBlock = self;  // BlockにselfInBlockを使います。
    • 他のobjective c対象を呼ばれたら、この対象がretainされてます。blockを終わる前、この対象自動にをreleaseされます.

この場合は__blockが要らない。


例えば、

typedef void (^MyBlock)(void);

// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"

// HelloWorldLayer
@interface
IntroLayer : CCLayer
{
}
@property
(nonatomic, copy) MyBlock      copiedBlock;
@property
(nonatomic, copy) NSString *      name;
@property
(nonatomic, assign) int               num;

@end


@implementation
IntroLayer

-(void) onEnter
{
   
[super onEnter];

   
int localVar = 10;

   
NSArray *testArray = [NSArray array];

    __block
ClassName *selfInBlock = self;
   
self.copiedBlock =  ^(void){
        selfInBlock
.name = @"wang";
        selfInBlock
.num = localVar + 100;

       
[testArray addObject:selfInBlock.name];

       
// testArray will be released automatically.
       
// [testArray release];
   
};

   
[self scheduleOnce:@selector(makeTransition:) delay:1];
}

-(void) makeTransition:(ccTime)dt
{
   
self.copiedBlock();
}
@end

use __block

もし

[testArray release];

をめんどくさいと思って、__blockを使います。

  • local変数
    • __blockを使ったら、blockに変更で来ます。
  • objective c対象
    • __blockを使ったら、この対象をretainされてないので、release必要がない。

selfじゃないobjectは__blockを使わないほうがいいです、自動にreleaseされますから。

-(void) onEnter
{
   
[super onEnter];

    __block
int localVar = 10;

 
// selfじゃないobjectは__blockを使わないほうがいいです、自動にreleaseされますから。
    __block
NSArray *testArray = [NSArray array];

    __block
ClassName *selfInBlock = self;
   
self.copiedBlock =  ^(void){
        selfInBlock
.name = @"wang";
        selfInBlock
.num = localVar + 100;

        localVar
= 11;       // localVarを変更出来る。
       
[testArray addObject:selfInBlock.name];
   
};

   
[self scheduleOnce:@selector(makeTransition:) delay:1];
}


以上です。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值