事情是这样的,最近在优化项目,有一个类似于新闻的资讯的页面,当不断加载更多,加载到n次后 收到 memory warning 没过多久项目就crash。通过检查代码,才发现是计算cell 的 height的方法出问题了。因为cell的高度是根据该新闻来变化,纯文字一种样式、文字加图片一种样式、多张图片一种样式等。这样就需要根据数据来决定cell的高度。
以下代码就是导致内存不断增加,而且 @autoreleasepool 无法释放该内存
UITableViewCellName *cell = [UITableViewName dequeueReusableCellWithIdentifier:@"cell"];
CGFloat height = [cell updateWithData:data];
当我不断加载更多数据,上图的 Memory不断上升,一直到400MB之后,就收到memory warning ,再刷几次,就crash。
并出现以下 crash 错误:
App(453,0x1a0063000) malloc: *** mach_vm_map(size=491520) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
App(453,0x1a0063000) malloc: *** mach_vm_map(size=98304) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
App(453,0x1a0063000) malloc: *** mach_vm_map(size=81920) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
2016-08-31 12:15:42.306 App[453:74162] UMLOG: error: session_id=1694E2101F9536008946C0FD651B5737, context=*** -[NSConcreteMutableData appendBytes:length:]: unable to allocate memory for length (65687)
(null)
((
0 CoreFoundation 0x0000000181ff6e50 <redacted> + 148
1 libobjc.A.dylib 0x000000018165bf80 objc_exception_throw + 56
2 CoreFoundation 0x0000000181ff6d80 <redacted> + 0
3 Foundation 0x00000001828fe64c <redacted> + 660
4 Foundation 0x00000001828fe2f4 <redacted> + 372
5 ImageIO 0x0000000183ab8fa8 <redacted> + 152
6 ImageIO 0x0000000183ac3a08 <redacted> + 44
7 ImageIO 0x0000000183ac3e4c <redacted> + 56
8 ImageIO 0x0000000183b21e94 <redacted> + 68
9 ImageIO 0x0000000183b2217c <redacted> + 348
10 ImageIO 0x0000000183ac5e10 <redacted> + 3092
11 ImageIO 0x0000000183ac4864 <redacted> + 776
12 ImageIO 0x0000000183ac2ca4 <redacted> + 5100
13 ImageIO 0x0000000183ac1888 <redacted> + 200
14 ImageIO 0x0000000183aaf28c CGImageDestinationFinalize + 656
15 UIKit 0x0000000187368ba8 UIImagePNGRepresentation + 512
16 UIKit 0x000000018742dbf0 <redacted> + 44
17 UIKit 0x000000018742de54 <redacted> + 248
18 Foundation 0x0000000182942b80 <redacted> + 1180
19 UIKit 0x00000001874f58d0 <redacted> + 140
20 Foundation 0x0000000182942b80 <redacted> + 1180
21 Foundation 0x00000001829499e8 <redacted> + 172
22 App 0x00000001002e2dfc -[CycleScrollView duplicate:] + 76
23 App 0x00000001002e2560 -[CycleScrollView setScrollViewContentDataSource] + 1764
24 App 0x00000001002e1964 -[CycleScrollView configContentViews] + 196
25 App 0x00000001002e294c -[CycleScrollView scrollViewDidScroll:] + 364
26 UIKit 0x0000000187469478 <redacted> + 76
27 UIKit 0x000000018715ef84 <redacted> + 460
28 UIKit 0x00000001871fa6e4 <redacted> + 724
29 App 0x00000001002e2c8c -[CycleScrollView animationTimerDidFired:] + 504
30 Foundation 0x00000001829cd008 __NSFireTimer + 88
31 CoreFoundation 0x0000000181fad81c <redacted> + 28
32 CoreFoundation 0x0000000181fad4c0 <redacted> + 884
33 CoreFoundation 0x0000000181faabd4 <redacted> + 1520
34 CoreFoundation 0x0000000181ed4d10 CFRunLoopRunSpecific + 384
35 GraphicsServices 0x00000001837bc088 GSEventRunModal + 180
36 UIKit 0x00000001871a9f70 UIApplicationMain + 204
37 App 0x000000010039fdb0 main + 124
38 libdyld.dylib 0x0000000181a728b8 <redacted> + 4
)
错误提示意思是内存不足,无法再分配内存。
问题找到了,解决办法就是:
if (!_cell) {
_cell = [[UITableViewCellName alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
CGFloat height = [cell updateWithData:data];
这是通过创建一个cell的成员变量,这个cell就是用来计算该cell所需的height,而且只会有一个cell,不会每一个数据都创建一个cell。
此时,再试试不断加载更多,看看memory 的情况
红色箭头所指的地方就是 系统收到 “Received memory warning.”的警告时,清了一次内存,瞬间memory下降了,就出现这种“陡坡”。
这个时候,我终于看懂如何看 这个xcode自带的 memory 功能。