メモリリークダウンARC

メモリリークは、コレート下ARCによって引き起こされ、参照する必要がある場合は、しばらくの間、他の人のブログや自分の理解のいくつかを見て、要約のために!エラーがある場合はお知らせ私のメールボックス([email protected])を送信することができますありがとうございました

反復

生成されたアレイを介して第1バグ

      
      
1
2
3
4
5
6
7
8
9
10
      
      
NSMutableArrayの* ARR = [NSMutableArrayのarrayWithArray:[] "H" @ "G" @ "F" @ "E" @ "D" @ "C" @ "B" @ "A"、、、、、、、@ ];
(NSStringの* ARRにおけるSTR){用
IF([isEqualToString STR: "F" @]){
[REMOVEOBJECT ARR:STR]。
}
}

エラー
SS

原因:オブジェクト・タイプが弱参照、配列要素が見つからない対応するオブジェクトを生じる放出される
バックプラスブレークの除去を、直接的に崩壊しないであろう

2.なしバグ

      
      
1
2
3
4
5
6
      
      
以下のために(INT i = 0; iは<arr.count; iは++){
NSStringの* STR = ARR [i]は、
IF([isEqualToString STR: "F" @]){
[REMOVEOBJECT ARR:STR]。
}
}

原因:NSString * str = arr[i]因为 NSString 对对象默认是 Strong 强引用,所以对移除的 str 持有了一份就不会因为 arr 中的对象被释放而产生 bug

3. 第三种遍历

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
      
      
NSMutableArray * arr;
{
Person * p1 = [[Person alloc] init];
Person * p2 = [[Person alloc] init];
Person * p3 = [[Person alloc] init];
Person * p4 = [[Person alloc] init];
Person * p5 = [[Person alloc] init];
Person * p6 = [[Person alloc] init];
arr = [NSMutableArray arrayWithArray:@[p1,p2,p3,p4,p5,p6]];
}
//由于 arr 对于 person 持有所以 person 不会被释放!
[arr enumerateObjectsUsingBlock:^(Person* p,NSUInteger idx,BOOL* _Nonnullstop) {
if (idx == 2) {
[arr removeObjectAtIndex:idx];
}
}];
//将 p3 移除后,在这个作用域之后被释放,其他的 person 会在 arr 出了作用域后被释放。

原因:当Person出第一个作用域时不会被释放,因为arr 对其持有一份 retainCount+1,在遍历时将其中一个元素移除出了作用域(遍历的)就会立刻被释放,其他的当arr 完成遍历之后出了 arr 所在作用域会被释放。

@try@catch@finally

      
      
1
2
3
4
5
6
7
8
9
10
11
12
      
      
@try {
Toys * toy = [[Toys alloc] init];
Person * p7 = [arr objectAtIndex:7];
//无法被执行
p7.beer = toy;
}
@catch (NSException *exception) {
NSLog(@"捕捉到的异常是:%@", exception);
}
@finally {
}

原因:因为取数组中第7个Person数组越界,之后的代码不会被执行导致Toys对象创建后无法被释放,导致内存泄漏。

performSelector

      
      
1
2
3
      
      
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self performSelector:@selector(test:) withObject:arr afterDelay:3];
});

原因: test 方法无法被调用,因为子线程中没有定时器。
performSelector 关于内存管理的执行原理是这样的执行 [self performSelector:@selector(test:) withObject:object afterDelay:3]; 的 时候,系统会将object的引用计数加1,执行完这个方法时,还会将object的引用计数减1,由于延迟这时object的 引用计数没有减少到0,也就导致了切换场景dealloc方法没有被调用,出现了内存泄露。
所以最后我的解决办法就是取消那些还没有来得及执行的延时函数,代码很简单:

      
      
1
      
      
[NSObject cancelPreviousPerformRequestsWithTarget:self]

当然你也可以一个一个得这样用:

      
      
1
      
      
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(test:) object:nil]

加上了这个以后,切换场景也就很顺利地执行了dealloc方法,至此问题解决!

NSTimer

在使用 NSTimer addtarget 时,为了防止 target 被释放而导致的程序异常,timer 会持有 target,所以这也是一处内存泄露的隐患。

      
      
1
      
      
_timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(timerTest) userInfo:nil repeats:YES];

それは、ターゲットリードretainCountタイマーが> = 1ですので、あなたは自己NSTimer強くない参照の放出をもたらす、deallocメソッドを呼び出すことはできません。

addObserver

その理由NSNotificationcenterは、あなたがそれを削除しない場合、それはメッセージを送信するためにオブザーバーであり続けることをremoveObserver必要です。観察者がこの時点でリリースされている場合は、メッセージが他のオブジェクトに転送され、それが深刻な問題を引き起こす可能性があり、[メッセージングメカニズムを理解します]

オリジナル:大列  ARCメモリリークの下で


おすすめ

転載: www.cnblogs.com/wangziqiang123/p/11641529.html