Une variante du code ci-dessous utilisé pour fonctionner, mais maintenant je reçois une fuite de mémoire comme vous pouvez le voir dans la capture d'écran ci-dessous. J'ai déplacé le code d'un thread différent à un événement TimerElapsed (voir trace de la pile dans la capture d'écran), fait diverses mises à jour de code et mises à niveau vers MD 3.0.3.4 et MT 5.3.4. Malheureusement, je n'arrive pas à comprendre pourquoi ça ne marche plus. Revenir à une version précédente du code où il est appelé à partir d'un fil régulier ne semble pas fonctionner non plus. Est-ce un bug dans la version actuelle de MD ou MT? Comme vous pouvez le voir, j'utilise NSAutoReleasePool en plus de forcer un garbage collect à la fin et ça ne marche toujours pas!fuite de mémoire Monotouch
EDIT: Je ai ajouté le code ci-dessous qui retrace l'unpackedImage de sa déclaration par DrawCustomImage, puis dans SetImages() comme paramètre "imageToSet", puis dans overlayImage() comme paramètre "overlay". SetImage appelle le code à l'intérieur sur le thread principal car lorsqu'il appelle finalement UpdateLiveScreen (avec l'overlayedImage qui en résulte), il dessine réellement à l'écran.
static UIImage unpackedImage = new UIImage();
public static void DrawCustomImage(IntPtr buffer, int width, int height, int bytesPerRow, CGColorSpace colSpace, byte[] rawPixels, ref UIImage unpackedImage)
{
using (var pool = new NSAutoreleasePool())
{
GCHandle pinnedArray = GCHandle.Alloc(rawPixels, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
// Set a grayscale drawing context using the image buffer
CGBitmapContext context = new CGBitmapContext(pointer, width, height, 8, bytesPerRow, colSpace, CGImageAlphaInfo.None);
try
{
// Convert the drawing context to an image and set it as the unpacked image
//using (var pool = new NSAutoreleasePool())
{
using (var img = context.ToImage())
{
unpackedImage = UIImage.FromImage(img);
}
}
} finally
{
pinnedArray.Free();
if (context != null)
context.Dispose();
}
}
GC.Collect();
}
SetImages(labelText, symbolArray[0], unpackedImage, points);
public static void SetImages(String labelText, UIImage symbol, UIImage imageToSet, PointF[] points)
{
appReference.InvokeOnMainThread(delegate
{
int imageWidth = 716;
int imageHeight = (int)imageToSet.Size.Height;
int nextFreeMainImageColumn = 5; // This gets set dynamically, but is simplified here for readability
lock (displayLocker)
{
// Get the current doppler image
UIImage mainImage = GetMainImage();
// Add the new imageToSet to the current image by overlaying it adjacent to the current image
UIImage overlayedImage = overlayImage(mainImage, imageToSet,
new RectangleF(0, 0, imageWidth, imageHeight),
new RectangleF(nextFreeMainImageColumn, 0, imageToSet.Size.Width, imageHeight));
// Update the live screen with the updated image and frame number
LiveCont.UpdateLiveScreen(labelText, symbol, overlayedImage, points);
}
});
}
public static UIImage overlayImage(UIImage image, UIImage overlay, RectangleF imageBoundingBox, RectangleF overlayBoundingBox)
{
int numBytes = 4; // Four bytes per pixel for a color image (Alpha, Red, Green, Blue)
int bytesPerRow = (int)imageBoundingBox.Width * numBytes;
// Set a color drawing context
CGBitmapContext context = new CGBitmapContext(
IntPtr.Zero,
(int)imageBoundingBox.Width,
(int)imageBoundingBox.Height,
8,
bytesPerRow,
CGColorSpace.CreateDeviceRGB(),
CGImageAlphaInfo.NoneSkipFirst
);
UIImage overlayedImage = null;
try
{
context.DrawImage(imageBoundingBox, image.CGImage); // Draw the main image
context.DrawImage(overlayBoundingBox, overlay.CGImage); // Draw the overlay
using (var img = context.ToImage())
{
overlayedImage = UIImage.FromImage(img); // Convert the context back to an image
}
}
finally
{
if (context != null)
context.Dispose();
image.Dispose();
}
return overlayedImage;
}
Je suis revenu à MT 5.2.12 et le problème a disparu, donc il doit y avoir un bug dans le code MT entre MT 5.2.12 et 5.3.4. – nbonwit