ARC down memory leaks

For memory leaks caused by ARC under collate and summarize, look for a moment other people's blog and some of their own understanding, if there is a need for reference! If there is an error you can send my mailbox ([email protected]) inform Thank you

Iterate

bug 1. The first through the array generated

      
      
1
2
3
4
5
6
7
8
9
10
      
      
NSMutableArray * arr = [NSMutableArray arrayWithArray:@[@"a",@"b",@"c",@"d",@"e",@"f",@"g",@"h"]];
for (NSString * str in arr) {
if ([str isEqualToString:@"f"]) {
[arr removeObject:str];
}
}

An error
ss

Cause: The object type is weak references, array element is released resulting in the corresponding object can not be found
in the removal of the back plus break, directly out will not collapse

2. no bug

      
      
1
2
3
4
5
6
      
      
for (int i = 0; i < arr.count; i ++) {
NSString * str = arr[i];
if ([str isEqualToString:@"f"]) {
[arr removeObject: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];

Because it is target lead retainCount timer is> = 1, you can not call dealloc method, resulting in the release of the self NSTimer not strong reference.

addObserver

The reason NSNotificationcenter need removeObserver that if you do not remove it, it will continue to be an observer to send the message. If the observer has been released at this time, the message will be forwarded to other objects, it may cause serious problems [understanding messaging mechanism]

Original: Large column  under ARC memory leak


Guess you like

Origin www.cnblogs.com/wangziqiang123/p/11641529.html