アプリのメモリが不足しています。これを解決するために、フレームバッファーを画像に書き込む関数で使用されている 2 つの非常に大きな配列を解放します。メソッドは次のようになります。
-(UIImage *) glToUIImage {
NSInteger myDataLength = 768 * 1024 * 4;
// allocate array and read pixels into it.
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, 768, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// gl renders "upside down" so swap top to bottom into new array.
// there's gotta be a better way, but this works.
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
for(int y = 0; y <1024; y++)
{
for(int x = 0; x <768 * 4; x++)
{
buffer2[(1023 - y) * 768 * 4 + x] = buffer[y * 4 * 768 + x];
}
}
// make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, NULL);
// prep the ingredients
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * 768;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
// make the cgimage
CGImageRef imageRef = CGImageCreate(768, 1024, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
// then make the uiimage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];
//free(buffer);
//free(buffer2);
return myImage;
}
最後に free(buffer) と free(buffer2) の 2 つが呼び出されていることに注意してください。これらは iPad シミュレーターで問題なく動作し、メモリの問題を取り除き、無礼に生成できるようにします。ただし、iPad は即座に殺されます。同様に、初めて実行します。free() 呼び出しを削除すると、問題なく実行されますが、1、2 分後にメモリが不足します。では、なぜ free() 呼び出しがデバイスをクラッシュさせるのでしょうか?
注 - デバイスを明示的にクラッシュさせるのは free() の呼び出しではなく、後でクラッシュします。しかし、それが根本的な原因のようです/..
編集 - 誰かが正確にクラッシュする場所について尋ねられました。このフローは、画像を別のオブジェクトに返し、ファイルに書き込みます。「UIImageJPEGRepresentation」メソッドを呼び出すと、EXT_BAD_ACCESS メッセージが生成されます。これは、ファイルに書き込むために渡す UIImage が破損しているか、null であるか、または他の何かであることが原因であると想定しています。しかし、これは、これら 2 つのバッファーを解放したときにのみ発生します。
メモリが何らかの形で UIIMage に関連しているかどうかは理解できますが、特にシミュレータで動作するため、実際にはそうすべきではありません。iPadが「無料」通話を処理する方法にかかっているのではないかと思いました...