2015-11-20 3 views
1

Я пытаюсь отобразить экран моего mac на iphone. У меня есть этот метод в делегате приложения Mac для захвата screeen в строку base64.Проблемы с памятью с ARC на iOS и Mac

-(NSString*)baseString{ 
CGImageRef screen = CGDisplayCreateImage(displays[0]); 

CGFloat w = CGImageGetWidth(screen); 
CGFloat h = CGImageGetHeight(screen); 

NSImage * image = [[NSImage alloc] initWithCGImage:screen size:(NSSize){w,h}]; 
[image lockFocus]; 
NSBitmapImageRep *bitmapRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:NSMakeRect(0, 0, w, h)]; 
[bitmapRep setCompression:NSTIFFCompressionJPEG factor:.3]; 
[image unlockFocus]; 

NSData *imageData = [bitmapRep representationUsingType:NSJPEGFileType properties:_options]; 
NSString *base64String = [imageData base64EncodedStringWithOptions:0]; 
image = nil; 
bitmapRep = nil; 
imageData = nil; 

return base64String;} 

после этого отправлю на iphone и представим его в UIImageView. Задержка между снимками экрана составляет 40 миллисекунд. Все работает так, как ожидается, пока не будет достаточно памяти. По истечении минуты потоковой передачи он начинает заменять и использовать 6 ГБ оперативной памяти. Использование памяти приложений iOS также растет линейно. К тому моменту, когда iOS достигает 90 МБ оперативной памяти, Mac имеет 6 ГБ. Даже если я остановку потоковой памяти не освобождается. Я использую ARC в обоих проектах. Не имеет значения, перенося ли его на ручной подсчет ссылок?
Я также пробовал блок @autoreleasepool {...}, но это не помогло.
Любые идеи?

EDIT

Мой IOS код здесь

NSString message = [NSString stringWithFormat:@"data:image/png;base64,%@",base64]; 
NSURL *url = [NSURL URLWithString:message]; 
NSData *imageData = [NSData dataWithContentsOfURL:url]; 

UIImage *ret = [UIImage imageWithData:imageData]; 
self.image.image = ret; 
+0

Вы прочитали документы для 'CGDisplayCreateImage'? – rmaddy

+0

Я использовал образец кода Apple для захвата экрана, хотя, хотя NSData вызывал утечки – Heisenbug

+0

'NSData' будет автореализован. – rmaddy

ответ

1

У вас есть серьезная утечка памяти. В документах для CGDisplayCreateImage четко указано:

Вызывающий отвечает за освобождение изображения, созданного при вызове CGImageRelease.

Обновить код с вызовом:

CGImageRelease(screen); 

Я хотел бы добавить, что только после создания NSImage.

+0

Вздох ... Вы отправили свой ответ, пока я редактировал мой ... :) –

1

Мы не можем помочь с утечками памяти iOS, так как вы не разместили свой код iOS, но я вижу большую утечку памяти в вашем коде Mac.

Вы вызываете функцию Core Foundation, CGDisplayCreateImage. Объекты Core Foundation не управляются ARC. Если функция Core Foundation имеет «Создать» (или «копировать») в имени, то она следует за «create rule», и вы несете ответственность за освобождение возвращенного объекта CF, когда вы закончите с ним.

Некоторые объекты CF имеют специальные звонки по освобождению. Для тех, кто этого не делает, просто позвоните CFRelease. CGImageRef имеет специальный выпуск, CGImageRelease().

Необходимо позвонить по телефону CGImageRelease(screen), возможно, после звонка на номер initWithCGImage.

+0

Спасибо, я использовал пример кода ScreenCapture Apple, и они не выпустили его после захвата. Спасибо за помощь !!это мой код iOS 'message = [NSString stringWithFormat: @" data: image/png; base64,% @ ", message]; NSURL * url = [NSURL URLWithString: message]; NSData * imageData = [NSData dataWithContentsOfURL: url]; UIImage * ret = [UIImage imageWithData: imageData]; self.image.image = ret; ' – Heisenbug

Смежные вопросы