FIXED:我不確定爲什麼。代碼已經在下面更新,並且在底部註釋CGImage/UIImage傳遞導致EXE-BAD-ACCESS
我有一個非常奇怪的錯誤,在模擬器上不顯示(即使運行樂器時),除非我打開所有的殭屍和調試選項。但是,一分鐘更新後(每秒更新1次)它會使手機崩潰。我有一個二維數組,我採取了一個子集,應用一個色彩映射,並轉變成一個圖像(這個數組不斷變化)。然後,我將該圖像傳遞給模型,並且一旦它接收到更新通知,viewcontroller就從模型中抓取它。我將佈局3類-Spectrogram,模型,視圖控制器:
下面是每個重要位(還有更多,但不相關):
Spectrogram.h(對不起,我不能讓這個正確縮進放在這裏)
@interface: Spectrogram : NSObject
{
NSMutableData *arrayData;
}
//renamed so Xcode allows the object with +1 reference count to be returned
- (CGImageRef)newSpectrogramImage;
Spectrogram.m
@implementation Spectrogram
- (CGImageRef)newSpectrogramImage
{
//slightly reordered
NSMutableData *imageData = [[NSMutableData alloc] init];
...code to go through arrayData and colormap it (get RGB transform) and store in imageData...
CGImageRef arrayImage = nil;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//specifically tell CGImage there is no alpha channel
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaNone;
//Use the toll-free bridge between NSData and CFData
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)imageData);
arrayImage = CGImageCreate((slices-startSlice), bins, 8, 24, 3*(slices-startSlice), colorSpace, bitmapInfo, provider, NULL, false, kCGRenderingIntentDefault); //image is rotated now, so width and height are switched
CGColorSpaceRelease(colorSpace);
CGDataProviderRelease(provider);
CGImageRelease(arrayImage);
[imageData release];
//Pass the CGImageRef with a reference count of 1
return arrayImage;
}
Model.h
@interface: Model : NSManagedObject
{
Spectrogram *spectrogram;
}
//Function the viewController can call to get the update
- (CGImageRef)newSpectrogramImage;
Model.m
@implementation Model
... there is a function that adds new data to the array and notifies all listeners...
- (CGImageRef)newSpectrogramImage {
return [spectrogram newSpectrogramImage];
}
ViewController.h
@interface: ViewController : UIViewController
{
}
//the root controller actually alloc's the record, and sets this property when creating this view
@property (nonatomic, retain) Record *currentRecord;
ViewController.m
@implementation ViewController
@synthesize spectrogramView;
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter ... listen for model updates...
}
//now, the real meat
- (void)recordUpdated:(NSNotification*)notification
{
CALayer *myLayer = self.view.layer;
CGImageRef spectrogramImage = nil;
spectrogramImage = [currentRecord newSpectrogramImage];
myLayer.contents = (id)spectrogramImage;
CGImageRelease(spectrogramImage);
}
我在最後一天改變了這個這麼多次試圖追捕何處以及爲何失敗。我嘗試過傳遞CGImageRef(但因爲這不是一個對象,所以我很擔心複製什麼可以是一個巨大的圖像),但它仍然失敗。它在模擬器中完美運行(將運行數十分鐘)。但在iphone上一分鐘內失敗,或者如果我打開模擬器的調試選項(一旦加載viewcontroller,它將會失敗)。
在附註中,這可能有些用處。這個視圖控制器作爲模式視圖加載時,手機側轉(偉大的工程)。但是,我在那裏有很多NSLogs,我發現這個viewcontroller的dealloc在mainviewcontroller甚至被viewwilldisappear之前調用 - 但它仍然運行。然後當手機返回並且視圖消失時,再次調用該控制器的dealloc。
注意 在模擬器中運行良好的版本將CGImageRefs一直傳遞給viewController而不是UIImages。我已經嘗試了至少50個不同的CGImage中創建UIImage的組合,上面列出的僅僅是其中的一個(它們都最終失敗,或者立即失敗)。值得注意的是,與上面的代碼,如果我這樣做添加到ViewController modelUpdated:
CGSize size = currentModel.spectrogramImage.size;
NSLog(@"width: %f", size.width);
,並註釋掉它分配給spectrogramView,寬度正確地報告,所以UIImage的是越來越傳承下去,這只是沒有得到保留(這是我的理解EXE_BAD_ACCESS錯誤)。
另外,最近我收到關於
self.spectrogramImage = [spectrogram getSpectrogramImage];
線丹EXE_BAD_ACCESS。所以,我認爲這個錯誤可能在頻譜圖類中。即使CGImage和UIImage代碼是從蘋果公司的例子中獲得的。
固定音符 我讀了設置的CALayer的內容是第一個通過CGImageRef到視圖快得多的方式 - 沒有UIImage的中介。不幸的是,我只做了一些改變,所以我看不到每一次迭代。但是,我知道我有幾次非常類似這樣的事情,並且一直在崩潰。現在的問題是,當前編寫的程序會因EXE_BAD_ACCESS而崩潰。如果我提高引用計數(或者沒有釋放它),那麼它可以很好地工作,但對象會泄漏。我仍然不明白這是如何可能的。爲了使泄漏和BAD ACCESS之間的差異爲1(而不是2或更多)的引用計數。
在哪條線上發生錯誤訪問? – sergio
它只發生,如果我有self.spectrogramView.image =行在那裏。如果我發表評論,該視圖是無用的,但它不會崩潰(即使模型仍然將圖像保存到它自己的ivar中)。即使我將傳遞的對象從UIImage *切換到CGImageRef,這也是如此。 –
好的,所以我認爲你應該在你的代碼後面發佈:alloc/init'spectrogramView',以及你用這個對象做的任何事情; alloc/init'currentModel',以及你用這個對象做的任何事情...... – sergio