iOS内存泄露

iOS Block

2017-07-09  本文已影响6人  ThaiLanKing

block类型

根据Block在内存中的位置,系统把Block分为3类:NSGlobalBlock,NSStackBlock, NSMallocBlock;

只要没有对block外的变量进行引用,创建后的block就是NSGlobalBlock。相当于普通的函数,在内存中存在于程序代码段。

只要block对外部的变量进行引用的话,默认创建的就是NSStackBlock。

只有对NSStackBlock进行copy才会得到NSMallocBlock。NSMallocBlock在内存中存在堆中。在ARC的情况下会自动对NSStackBlock进行copy


//在ARC下很少出现NSStackBlock,因为 arc 下会自动往堆内存中copy,只有weak的时候才不会copy

int (^globalBlock)(int) = ^(int a){return a*a};

int v = 10;
int (^mallocBlock)(int) = ^(int a){return a*v};

__weak int (^stackBlock)(int) = ^(int a){return a*v};
NSLog(@"stackBlock %@", stackBlock);

对block自身内存的管理

  • Block被另一个Block使用时,另一个Block被copy到堆上时,被使用的Block也会被copy。但作为参数的Block是不会发生copy的。
  • 当 block 作为参数被传入方法名带有 usingBlock 的 Cocoa Framework 方法或 GCD 的 API 时。这些方法会在内部对传递进来的 block 调用 copy 或 _Block_copy 进行拷贝。

循环引用

系统API的循环引用

系统的某些block api中,UIView的block版本写动画时不需要考虑,但也有一些api需要考虑:


[UIView animateWithDuration:duration animations:^{ [self.superview layoutIfNeeded];}]; 
                                                    

[[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.someProperty = xyz;}];


[[NSNotificationCenter defaultCenter] addObserverForName:@"someNotification" 
            object:nil 
             queue:[NSOperationQueue mainQueue]
        usingBlock:^(NSNotification * notification) {
                                            self.someProperty = xyz; }]; 

__weak __typeof__(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^
{
__typeof__(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
} );

类似的:

__weak __typeof__(self) weakSelf = self;
_observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"testKey"
                                                                object:nil
                                                                 queue:nil
                                                            usingBlock:^(NSNotification *note) {
      __typeof__(self) strongSelf = weakSelf;
      [strongSelf dismissModalViewControllerAnimated:YES];
}];
  
self --> _observer --> block --> self 显然这也是一个循环引用。

上一篇下一篇

猜你喜欢

热点阅读