提问人:Dave Bradford 提问时间:10/27/2023 最后编辑:Dave Bradford 更新时间:10/27/2023 访问量:96
应用程序在 iOS 16 上崩溃,但不在 iOS 17 上崩溃。-
App crashing on iOS 16, but not iOS 17. -
问:
我有一个应用程序,可让您使用设备相机拍照 - 拍摄后,它会进入下一个屏幕进行编辑 - 但是,在 iOS 16 设备上,只要我从相机视图中按下“使用照片”按钮,它就会崩溃 - 由于某种原因,它不会发生在 iOS 17 设备上, 它对他们工作正常。 我尝试调试但没有成功。
#define IMAGE_FRAME_SIZE 5
#define FRAME_COLOR_R 1.0
#define FRAME_COLOR_G 1.0
#define FRAME_COLOR_B 1.0
#define FRAME_COLOR_ALPHA 1
//#define VIEW_AREA_WIDTH 320
//#define VIEW_AREA_HEIGHT 368
//#define IMAGEVIEW_MARGIN 20
#define VIEW_AREA_WIDTH ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 768 : 320)
#define VIEW_AREA_HEIGHT ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 800 : 368)
#define IMAGEVIEW_MARGIN ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 40 : 20)
#define SHADOW_WIDTH ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ? 16 : 8)
@interface PhotoSelectViewController ()
@end
@implementation PhotoSelectViewController
@synthesize popoverController;
@synthesize cameraPicker;
@synthesize backgroundImageView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if ([UIScreen mainScreen].bounds.size.height == 568)
self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"[email protected]"]];
else
self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"background.png"]];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.view setBounds:self.view.frame];
backgroundImageView.image = [[[GlobalData compressImage:[GlobalData sharedData].backgroundImage withSize:CGSizeMake((VIEW_AREA_WIDTH - IMAGEVIEW_MARGIN * 2), (VIEW_AREA_HEIGHT - IMAGEVIEW_MARGIN * 2))] imageAddFrame:IMAGE_FRAME_SIZE withColor:[UIColor colorWithRed:FRAME_COLOR_R green:FRAME_COLOR_G blue:FRAME_COLOR_B alpha:FRAME_COLOR_ALPHA].CGColor] imageWithShadow:SHADOW_WIDTH];
[backgroundImageView setFrame:CGRectMake(([UIScreen mainScreen].bounds.size.width - backgroundImageView.image.size.width) / 2, ([UIScreen mainScreen].bounds.size.height - backgroundImageView.image.size.height) / 2, backgroundImageView.image.size.width, backgroundImageView.image.size.height)];
}
该部分是崩溃发生的地方,如果我将一些代码移动到,那么应用程序会继续通过照片阶段并继续,但是当您返回再次尝试时,应用程序将崩溃,因此它几乎就像一次性修复,但下次崩溃,但它提供了一些可能出错的想法。viewWillAppear
viewdidLoad
我意识到它是硬编码的值,这是一个非常旧的应用程序,我只是想在改进其他部分之前修复错误
- (UIImage*)imageWithShadow:(int)shadowSize {
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef shadowContext = CGBitmapContextCreate(NULL, self.size.width + shadowSize, self.size.height + shadowSize, CGImageGetBitsPerComponent(self.CGImage), 0,
colourSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colourSpace);
CGContextSetShadowWithColor(shadowContext, CGSizeMake(shadowSize / 2, -shadowSize / 2), 6, [UIColor blackColor].CGColor);
CGContextDrawImage(shadowContext, CGRectMake(0, 10, self.size.width, self.size.height), self.CGImage);
CGImageRef shadowedCGImage = CGBitmapContextCreateImage(shadowContext);
CGContextRelease(shadowContext);
UIImage * shadowedImage = [UIImage imageWithCGImage:shadowedCGImage];
CGImageRelease(shadowedCGImage);
return shadowedImage;
}
编辑 - 下面的堆栈跟踪
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x8)
frame #0: 0x00000001ad11f4dc libobjc.A.dylib`objc_retain_x2 + 8
frame #1: 0x00000001e2f2088c TelephonyUI`-[UIImage(TelephonyUI) imageWithShadow:] + 40
* frame #2: 0x0000000104dea7cc Cut me in`-[PhotoSelectViewController viewWillAppear:](self=0x000000010637ed20, _cmd="viewWillAppear:", animated=YES) at PhotoSelectViewController.m:76:33
frame #3: 0x00000001b5df2880 UIKitCore`-[UIViewController _setViewAppearState:isAnimating:] + 612
frame #4: 0x00000001b5e8c6a8 UIKitCore`-[UIViewController __viewWillAppear:] + 100
frame #5: 0x00000001b5df4114 UIKitCore`-[UINavigationController viewWillAppear:] + 280
frame #6: 0x00000001b5df2880 UIKitCore`-[UIViewController _setViewAppearState:isAnimating:] + 612
frame #7: 0x00000001b5e8c6a8 UIKitCore`-[UIViewController __viewWillAppear:] + 100
frame #8: 0x00000001b64e4888 UIKitCore`__56-[UIPresentationController runTransitionForCurrentState]_block_invoke_3 + 740
frame #9: 0x00000001b5f7391c UIKitCore`-[_UIAfterCACommitBlock run] + 64
frame #10: 0x00000001b5f73858 UIKitCore`-[_UIAfterCACommitQueue flush] + 184
frame #11: 0x0000000105c87f08 libdispatch.dylib`_dispatch_call_block_and_release + 24
frame #12: 0x0000000105c897a0 libdispatch.dylib`_dispatch_client_callout + 16
frame #13: 0x0000000105c9834c libdispatch.dylib`_dispatch_main_queue_drain + 920
frame #14: 0x0000000105c97fa4 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 40
frame #15: 0x00000001b3edd9ac CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
frame #16: 0x00000001b3ec1648 CoreFoundation`__CFRunLoopRun + 2080
frame #17: 0x00000001b3ec5d20 CoreFoundation`CFRunLoopRunSpecific + 584
frame #18: 0x00000001eb23c998 GraphicsServices`GSEventRunModal + 160
frame #19: 0x00000001b615780c UIKitCore`-[UIApplication _run] + 868
frame #20: 0x00000001b6157484 UIKitCore`UIApplicationMain + 312
frame #21: 0x0000000104de4054 Cut me in`main(argc=1, argv=0x000000016b023670) at main.m:16:16
frame #22: 0x00000001d167c344 dyld`start + 1860
答:
0赞
Carl Lindberg
10/27/2023
#1
我怀疑还有另一种名为 -imageWithShadow 的方法实现:某处(从外观上看是一个私有的 TelephonyUI 框架),它采用对象参数而不是 int(可能是 NSShadow 参数)。你调用的是那个方法,而不是你认为的那个方法,并且该方法试图保留对象参数,但你传递了一个 int 值 8,所以它取消了对 0x8 的引用,作为保留参数的指针,然后崩溃了。将 imageWithShadow: 方法名称更改为更特定于项目的名称,可能带有 myapp_ 前缀(将类别方法添加到标准 Apple 类时总是一个好主意)。
TelephonyUI 可能在 iOS17 中更改了他们的方法名称,或者您的方法在那里“获胜”,而 TelephonyUI 会在需要它时崩溃。
评论
viewWillAppear
imageWithShadow
[super viewWillAppear:animated];
viewDidUnload
:(BOOL)animated
viewWillAppear
viewWillAppear:
UIViewController