2013-02-28 4 views
4

У меня есть приложение, в котором экран непрерывно захватывает фоновый поток. Вот кодobject c renderInContext crash on background thread

- (UIImage *) captureScreen { 

    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; 
    CGRect rect = [keyWindow bounds]; 
    UIGraphicsBeginImageContext(rect.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    [[keyWindow layer] renderInContext:context]; 
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    UIDeviceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 
    if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight) || (orientation==UIInterfaceOrientationPortraitUpsideDown)) { 
     img=[self rotatedImage:img]; 
    } 
    return img; 
} 

Он работает хорошо для захвата один или два раза. Но через некоторое время приложение вылетает всегда в одной строке [[keyWindow layer] renderInContext:context]; и дает сообщение EXC_BAD_ACCESS (code=1, address=0x8). Я искал везде и ничего полезного. Нашел только, что renderInContext имеет проблемы с утечкой памяти, когда он работает в фоновом потоке. Но, как вы понимаете, это не решает мою проблему :). Так есть 3 вопроса: -

  1. Что является причиной этой аварии (проблемы)?

  2. Что я могу сделать с этим?

  3. Есть ли другой способ захвата экрана (рядом с тем, что предлагает Apple, поскольку там также используется renderInContext). Что-то без рендеринга ...?

+0

Вы должны выполнить свои задачи, связанные с графическим интерфейсом, в главной теме – nsgulliver

+0

показать нам ваш код рендеринга. вы пытаетесь использовать основные объекты данных в потоке, на котором они не были созданы. вы используете неатомные свойства в вашем коде рендеринга. оба эти и более могут вызвать это. –

+0

Является ли какой-либо из 'layer' или' context' nil при вызове 'renderInContext'? Вызывается метод 'receivedMemoryWarning'? –

ответ

8

-renderInContext: не является потокобезопасным, и вы не можете его назвать из фоновой темы. Вам нужно будет сделать рисунок на основном потоке.

+0

Но если я делаю циклический захват в основном потоке, пользовательский интерфейс будет застревать, верно? Этот способ работает, но сбой, и может быть причина в том, что он не является потокобезопасным ... :(??? – Garnik

+0

Правильно, вы будете блокировать UI, пока вы делаете снимки экрана. Значит, вам придется найти удобный способ сделать это, выбросив HUD или что-то подобное. –

+0

У меня такая же проблема, на фоне поток renderincontext вылетает несколько раз. Можете ли вы расширить комментарий HUD? –

3

Мне нечего делать, кроме как выполнить этот метод в основной теме. Я реорганизовал свое управление потоками и может получить хороший результат для меня, как это сделать:

[self performSelectorOnMainThread:@selector(captureScreenOnMainThread) withObject:nil waitUntilDone: YES]; Последний параметр может быть установлен не в некоторых случаях ...

Спасибо за все ответы.