問題描述
我正在為一個更復雜的項目嘗試一個簡單的測試,但我很困惑為什么下面的代碼會崩潰并給出 EXC_BAD_ACCESS 錯誤?
I am trying a simple test for a much more complex project but I am baffled as to why the code below is crashing and giving an EXC_BAD_ACCESS error?
這是從 UIView 調用的.
This is called from a UIView.
- (void)testing {
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"ball.png" ofType:nil];
CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];
// CGImageRetain(imageRef);
UIImage *newImage = [[UIImage alloc]initWithCGImage:imageRef];
UIImageView *iv = [[UIImageView alloc]initWithImage:newImage];
[self addSubview:iv];
}
我的猜測是 CGImageRef 沒有被保留,而是添加了 CGImageRetain(imageRef);沒有區別.
My guess is that the CGImageRef is not being retained but adding CGImageRetain(imageRef); makes no difference.
我還應該注意,這個項目已經開啟了 ARC.
I should also note that this project has ARC turned on.
編輯
EDIT
我做了更多的測試,發現這與 ARC 直接相關,因為我創建了 2 個基本項目,其中僅包括上面的代碼.第一個關閉 ARC 并且效果很好.下一個打開 ARC 并且 BAM 崩潰并出現相同的錯誤.有趣的是,我只有在崩潰前第一次運行項目時才收到實際的日志錯誤.
I did a little bit more testing and have discovered that this is directly related to ARC as I created 2 basic projects including only the code above. The first with ARC turned off and it worked perfectly. The next with ARC turned on and BAM crash with the same error. The interesting thing is that I got an actual log error ONLY the first time I ran the project before the crash.
Error: ImageIO: ImageProviderCopyImageBlockSetCallback 'ImageProviderCopyImageBlockSetCallback' header is not a CFDictionary...
推薦答案
這行就是問題所在:
CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];
創建的 UIImage
將在此完整表達式之后立即釋放(例如,在此行之后).因此,即使嘗試在之后添加 CGImageRetain()
也行不通.
The created UIImage
will be released immediately following this full-expression (e.g. after this line). So even trying to add a CGImageRetain()
afterwards won't work.
根本問題是CGImage
返回的CGImageRef
幾乎肯定是UIImage
的一個ivar,當UIImage
被釋放.
The fundamental problem is the CGImageRef
returned from CGImage
is almost certainly an ivar of the UIImage
and will be released when the UIImage
is deallocted.
解決此問題的通用方法是延長 UIImage
的生命周期.您可以通過將 UIImage
放入局部變量并在最后一次引用 CGImage
之后引用它(例如,使用 (void)uiimageVar
).或者,您可以將 CGImageRef
保留在同一行,如
The generic way to fix this is to extend the lifetime of the UIImage
. You can do this by placing the UIImage
into a local variable and referencing it after your last reference to the CGImage
(e.g. with (void)uiimageVar
). Alternatively, you can retain the CGImageRef
on that same line, as in
CGImageRef imageRef = CGImageRetain([[[UIImage alloc] initWithContentsOfFile:imagePath] CGImage]);
但如果你這樣做了,別忘了在完成后釋放 imageRef
.
But if you do this, don't forget to release the imageRef
when you're done.
這篇關于來自 CGImageRef 的 UIImage的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!