问题描述
我正在使用ARC,有一个CustomTableViewController,并且正在向我的背景单元格,页眉和页脚中添加一个CustomView.
例如,在tableView:viewForFooterInSection
方法中,我输入了以下代码行:
- (UIView *) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
CustomFooter *footer = [[CustomFooter alloc] init];
return footer;
}
CustomFooter是UIView的子类,它使用- (void)drawRect:(CGRect)rect
当我在模拟器上运行该应用程序时,该应用程序运行正常,但是当我尝试在iPhone上运行时,该应用程序崩溃了.
我该如何解决?
这是我的崩溃报告:
Date/Time: 2012-06-28 12:37:07.168 +0200
OS Version: iPhone OS 5.1.1 (9B206)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000009
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x3508cf78 objc_msgSend + 16
1 CoreFoundation 0x372d5e90 CFRetain + 76
2 CoreFoundation 0x372dfb74 +[__NSArrayI __new::] + 48
3 CoreFoundation 0x372dfa8e -[__NSPlaceholderArray initWithObjects:count:] + 294
4 CoreFoundation 0x3730ce68 +[NSArray arrayWithObjects:] + 460
5 CustomTable 0x0004766e drawLinearGradient (Common.m:15)
6 CustomTable 0x00048c14 -[CustomFooter drawRect:] (CustomFooter.m:50)
7 UIKit 0x3107015e -[UIView(CALayerDelegate) drawLayer:inContext:] + 270
8 QuartzCore 0x374b74de -[CALayer drawInContext:] + 110
9 QuartzCore 0x374b6b38 CABackingStoreUpdate_ + 1776
10 QuartzCore 0x374b632e CA::Layer::display_() + 950
11 QuartzCore 0x374b5f5a CA::Layer::display() + 122
12 QuartzCore 0x374b5e9c CA::Layer::display_if_needed(CA::Transaction*) + 168
13 QuartzCore 0x374b5844 CA::Context::commit_transaction(CA::Transaction*) + 228
14 QuartzCore 0x374b5578 CA::Transaction::commit() + 308
15 QuartzCore 0x374dd90a CA::Transaction::flush() + 38
16 QuartzCore 0x374dd8dc +[CATransaction flush] + 28
17 UIKit 0x310a6108 -[UIApplication _reportAppLaunchFinished] + 36
18 UIKit 0x31093b2c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 1256
19 UIKit 0x31061abc -[UIApplication handleEvent:withNewEvent:] + 1004
20 UIKit 0x31061560 -[UIApplication sendEvent:] + 48
21 UIKit 0x31060f34 _UIApplicationHandleEvent + 5820
22 GraphicsServices 0x33aa3224 PurpleEventCallback + 876
23 CoreFoundation 0x3736151c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32
24 CoreFoundation 0x373614be __CFRunLoopDoSource1 + 134
25 CoreFoundation 0x3736030c __CFRunLoopRun + 1364
26 CoreFoundation 0x372e349e CFRunLoopRunSpecific + 294
27 CoreFoundation 0x372e3366 CFRunLoopRunInMode + 98
28 UIKit 0x31092864 -[UIApplication _run] + 544
29 UIKit 0x3108fcce UIApplicationMain + 1074
30 CustomTable 0x00046798 main (main.m:16)
31 CustomTable 0x0004673c start + 32
Thread 1 name: Dispatch queue: com.apple.libdispatch-manager
Thread 1:
0 libsystem_kernel.dylib 0x315343a8 kevent + 24
1 libdispatch.dylib 0x304b9ea4 _dispatch_mgr_invoke + 708
2 libdispatch.dylib 0x304b9bc2 _dispatch_mgr_thread + 30
Thread 2:
0 libsystem_kernel.dylib 0x31544cd4 __workq_kernreturn + 8
1 libsystem_c.dylib 0x33bfcf36 _pthread_wqthread + 610
2 libsystem_c.dylib 0x33bfccc8 start_wqthread + 0
Thread 3:
0 libsystem_kernel.dylib 0x31544cd4 __workq_kernreturn + 8
1 libsystem_c.dylib 0x33bfcf36 _pthread_wqthread + 610
2 libsystem_c.dylib 0x33bfccc8 start_wqthread + 0
Thread 4 name: WebThread
Thread 4:
0 libsystem_kernel.dylib 0x31534004 mach_msg_trap + 20
1 libsystem_kernel.dylib 0x315341fa mach_msg + 50
2 CoreFoundation 0x373613ec __CFRunLoopServiceMachPort + 120
3 CoreFoundation 0x37360124 __CFRunLoopRun + 876
4 CoreFoundation 0x372e349e CFRunLoopRunSpecific + 294
5 CoreFoundation 0x372e3366 CFRunLoopRunInMode + 98
6 WebCore 0x32c8cc9c _ZL12RunWebThreadPv + 396
7 libsystem_c.dylib 0x33c0272e _pthread_start + 314
8 libsystem_c.dylib 0x33c025e8 thread_start + 0
Thread 0 crashed with ARM Thread State:
r0: 0x00125860 r1: 0x30d16b7c r2: 0x3f9a3570 r3: 0x0014b170
r4: 0x00000001 r5: 0x2fe41188 r6: 0x0014b178 r7: 0x2fe4114c
r8: 0x0014b170 r9: 0x0c345adf r10: 0x00000002 r11: 0x00000001
ip: 0x3f97f814 sp: 0x2fe41140 lr: 0x372d5e97 pc: 0x3508cf78
cpsr: 0x00000030
这是我在CustomFooter中使用的drawRect函数:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef whiteColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0].CGColor;
CGColorRef lightGrayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0].CGColor;
CGColorRef darkGrayColor = [UIColor colorWithRed:187.0/255.0 green:187.0/255.0 blue:187.0/255.0 alpha:1.0].CGColor;
CGColorRef shadowColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.5].CGColor;
CGFloat paperMargin = 9.0;
CGRect paperRect = CGRectMake(self.bounds.origin.x+paperMargin,
self.bounds.origin.y,
self.bounds.size.width-paperMargin*2,
self.bounds.size.height);
CGRect arcRect = paperRect;
arcRect.size.height = 8;
CGContextSaveGState(context);
CGMutablePathRef arcPath = createArcPathFromBottomOfRect(arcRect, 4.0);
CGContextAddPath(context, arcPath);
CGContextClip(context);
drawLinearGradient(context, paperRect, lightGrayColor, darkGrayColor);
CGContextRestoreGState(context);
CGContextSaveGState(context);
CGPoint pointA = CGPointMake(arcRect.origin.x,
arcRect.origin.y + arcRect.size.height - 1);
CGPoint pointB = CGPointMake(arcRect.origin.x, arcRect.origin.y);
CGPoint pointC = CGPointMake(arcRect.origin.x + arcRect.size.width - 1,
arcRect.origin.y);
CGPoint pointD = CGPointMake(arcRect.origin.x + arcRect.size.width - 1,
arcRect.origin.y + arcRect.size.height - 1);
draw1PxStroke(context, pointA, pointB, whiteColor);
draw1PxStroke(context, pointC, pointD, whiteColor);
CGContextRestoreGState(context);
CGContextAddRect(context, paperRect);
CGContextAddPath(context, arcPath);
CGContextEOClip(context);
CGContextAddPath(context, arcPath);
CGContextSetShadowWithColor(context, CGSizeMake(0, 2), 3.0, shadowColor);
CGContextFillPath(context);
CFRelease(arcPath);
}
drawLinearGradient
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
JeremyP对数组初始化程序崩溃的分析是正确的.我猜想根本原因是:
CGColorRef whiteColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0].CGColor;
我的猜测是,由于您不使用UIColor
而不是在此语句之外创建,因此ARC会急切地发布它.这也意味着您没有以任何方式保留的CGColor
(并且ARC将不会为您保留)
UIColor *color = [UIColor ...];
CGColorRef cgColor = CFRetain(color.CGColor);
color = nil;
也会被释放并重新分配.
尝试对每种UIColor(类似于白色,只需使用[UIColor whiteColor]
)使用类似的方法进行处理:
UIColor *color = [UIColor ...];
CGColorRef cgColor = CFRetain(color.CGColor);
color = nil;
I'm using ARC, I have a CustomTableViewController and I'm adding a CustomView to my background cell, header and footer.
For example in the tableView:viewForFooterInSection
method i put these lines of code:
- (UIView *) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
CustomFooter *footer = [[CustomFooter alloc] init];
return footer;
}
CustomFooter is a subclass of UIView that draws a rectangle as background cell with - (void)drawRect:(CGRect)rect
When i runs the application on the simulator works but it crash when i try on my iPhone.
How can i fix it?
This is my crash report:
Date/Time: 2012-06-28 12:37:07.168 +0200
OS Version: iPhone OS 5.1.1 (9B206)
Report Version: 104
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000009
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libobjc.A.dylib 0x3508cf78 objc_msgSend + 16
1 CoreFoundation 0x372d5e90 CFRetain + 76
2 CoreFoundation 0x372dfb74 +[__NSArrayI __new::] + 48
3 CoreFoundation 0x372dfa8e -[__NSPlaceholderArray initWithObjects:count:] + 294
4 CoreFoundation 0x3730ce68 +[NSArray arrayWithObjects:] + 460
5 CustomTable 0x0004766e drawLinearGradient (Common.m:15)
6 CustomTable 0x00048c14 -[CustomFooter drawRect:] (CustomFooter.m:50)
7 UIKit 0x3107015e -[UIView(CALayerDelegate) drawLayer:inContext:] + 270
8 QuartzCore 0x374b74de -[CALayer drawInContext:] + 110
9 QuartzCore 0x374b6b38 CABackingStoreUpdate_ + 1776
10 QuartzCore 0x374b632e CA::Layer::display_() + 950
11 QuartzCore 0x374b5f5a CA::Layer::display() + 122
12 QuartzCore 0x374b5e9c CA::Layer::display_if_needed(CA::Transaction*) + 168
13 QuartzCore 0x374b5844 CA::Context::commit_transaction(CA::Transaction*) + 228
14 QuartzCore 0x374b5578 CA::Transaction::commit() + 308
15 QuartzCore 0x374dd90a CA::Transaction::flush() + 38
16 QuartzCore 0x374dd8dc +[CATransaction flush] + 28
17 UIKit 0x310a6108 -[UIApplication _reportAppLaunchFinished] + 36
18 UIKit 0x31093b2c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 1256
19 UIKit 0x31061abc -[UIApplication handleEvent:withNewEvent:] + 1004
20 UIKit 0x31061560 -[UIApplication sendEvent:] + 48
21 UIKit 0x31060f34 _UIApplicationHandleEvent + 5820
22 GraphicsServices 0x33aa3224 PurpleEventCallback + 876
23 CoreFoundation 0x3736151c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32
24 CoreFoundation 0x373614be __CFRunLoopDoSource1 + 134
25 CoreFoundation 0x3736030c __CFRunLoopRun + 1364
26 CoreFoundation 0x372e349e CFRunLoopRunSpecific + 294
27 CoreFoundation 0x372e3366 CFRunLoopRunInMode + 98
28 UIKit 0x31092864 -[UIApplication _run] + 544
29 UIKit 0x3108fcce UIApplicationMain + 1074
30 CustomTable 0x00046798 main (main.m:16)
31 CustomTable 0x0004673c start + 32
Thread 1 name: Dispatch queue: com.apple.libdispatch-manager
Thread 1:
0 libsystem_kernel.dylib 0x315343a8 kevent + 24
1 libdispatch.dylib 0x304b9ea4 _dispatch_mgr_invoke + 708
2 libdispatch.dylib 0x304b9bc2 _dispatch_mgr_thread + 30
Thread 2:
0 libsystem_kernel.dylib 0x31544cd4 __workq_kernreturn + 8
1 libsystem_c.dylib 0x33bfcf36 _pthread_wqthread + 610
2 libsystem_c.dylib 0x33bfccc8 start_wqthread + 0
Thread 3:
0 libsystem_kernel.dylib 0x31544cd4 __workq_kernreturn + 8
1 libsystem_c.dylib 0x33bfcf36 _pthread_wqthread + 610
2 libsystem_c.dylib 0x33bfccc8 start_wqthread + 0
Thread 4 name: WebThread
Thread 4:
0 libsystem_kernel.dylib 0x31534004 mach_msg_trap + 20
1 libsystem_kernel.dylib 0x315341fa mach_msg + 50
2 CoreFoundation 0x373613ec __CFRunLoopServiceMachPort + 120
3 CoreFoundation 0x37360124 __CFRunLoopRun + 876
4 CoreFoundation 0x372e349e CFRunLoopRunSpecific + 294
5 CoreFoundation 0x372e3366 CFRunLoopRunInMode + 98
6 WebCore 0x32c8cc9c _ZL12RunWebThreadPv + 396
7 libsystem_c.dylib 0x33c0272e _pthread_start + 314
8 libsystem_c.dylib 0x33c025e8 thread_start + 0
Thread 0 crashed with ARM Thread State:
r0: 0x00125860 r1: 0x30d16b7c r2: 0x3f9a3570 r3: 0x0014b170
r4: 0x00000001 r5: 0x2fe41188 r6: 0x0014b178 r7: 0x2fe4114c
r8: 0x0014b170 r9: 0x0c345adf r10: 0x00000002 r11: 0x00000001
ip: 0x3f97f814 sp: 0x2fe41140 lr: 0x372d5e97 pc: 0x3508cf78
cpsr: 0x00000030
This is my drawRect function into CustomFooter:
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef whiteColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0].CGColor;
CGColorRef lightGrayColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1.0].CGColor;
CGColorRef darkGrayColor = [UIColor colorWithRed:187.0/255.0 green:187.0/255.0 blue:187.0/255.0 alpha:1.0].CGColor;
CGColorRef shadowColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.5].CGColor;
CGFloat paperMargin = 9.0;
CGRect paperRect = CGRectMake(self.bounds.origin.x+paperMargin,
self.bounds.origin.y,
self.bounds.size.width-paperMargin*2,
self.bounds.size.height);
CGRect arcRect = paperRect;
arcRect.size.height = 8;
CGContextSaveGState(context);
CGMutablePathRef arcPath = createArcPathFromBottomOfRect(arcRect, 4.0);
CGContextAddPath(context, arcPath);
CGContextClip(context);
drawLinearGradient(context, paperRect, lightGrayColor, darkGrayColor);
CGContextRestoreGState(context);
CGContextSaveGState(context);
CGPoint pointA = CGPointMake(arcRect.origin.x,
arcRect.origin.y + arcRect.size.height - 1);
CGPoint pointB = CGPointMake(arcRect.origin.x, arcRect.origin.y);
CGPoint pointC = CGPointMake(arcRect.origin.x + arcRect.size.width - 1,
arcRect.origin.y);
CGPoint pointD = CGPointMake(arcRect.origin.x + arcRect.size.width - 1,
arcRect.origin.y + arcRect.size.height - 1);
draw1PxStroke(context, pointA, pointB, whiteColor);
draw1PxStroke(context, pointC, pointD, whiteColor);
CGContextRestoreGState(context);
CGContextAddRect(context, paperRect);
CGContextAddPath(context, arcPath);
CGContextEOClip(context);
CGContextAddPath(context, arcPath);
CGContextSetShadowWithColor(context, CGSizeMake(0, 2), 3.0, shadowColor);
CGContextFillPath(context);
CFRelease(arcPath);
}
drawLinearGradient
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
JeremyP's analysis of the array initializer crash is correct. I'm guessing the root cause is:
CGColorRef whiteColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0].CGColor;
My guess is that since you don't use the UIColor
you create beyond this statement, it will be eagerly released by ARC. That also means that the CGColor
that you didn't retain in any way (and which ARC won't retain for you) is probably also released and dealloced.
Try working it around with something like this for each of the UIColors (and for the white one, just use [UIColor whiteColor]
):
UIColor *color = [UIColor ...];
CGColorRef cgColor = CFRetain(color.CGColor);
color = nil;
这篇关于EXC_BAD_ACCESS与ARC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!