Xcode 4.2.1: NSThread вызывает утечку памяти с использованием ARC

Я приближаюсь к концу школьного проекта по программированию в Xcode, но прямо сейчас у меня есть небольшая, но крайне раздражающая проблема: утечка памяти. Утечка была прослежена до следующей строки кода:

@autoreleasepool {
    [NSThread detachNewThreadSelector:@selector(updateThread) toTarget:self withObject:nil];
}

Когда я прокомментирую это, утечка исчезнет. По-видимому, что-то идет не так в autoreleasepool: я все еще немного новичок в этом (особенно при использовании ARC), но такие потоки, как этот дал мне понять, что использования @autoreleasepool должно быть достаточно.

По какой-то причине это не относится к моему коду. Думаю, я что-то здесь упускаю: если кто-то может дать несколько идей о том, в чем может быть проблема, то это будет очень признательно. Просто скажите мне, если мне нужно опубликовать больше кода, это не будет проблемой: просто для удобочитаемости вопроса я стараюсь ограничить его основной проблемой.

Заранее спасибо!

РЕДАКТИРОВАТЬ:

Спасибо за первые ответы! Однако проблема все еще сохраняется... Я опубликую еще немного кода, чтобы немного прояснить ситуацию. Поток запускается в viewDidLoad:

/*
 Everything mentioned here will be done after loading.
 */
- (void)viewDidLoad
{
    // Do standard setup
    [super viewDidLoad];

    // Do any additional setup before loading the view from its nib.
    self.title = @"Blog Manager";

    // Activate edit mode
    [tbvBlogList setEditing:YES animated:YES];
    tbvBlogList.allowsSelectionDuringEditing = YES;

    [NSThread detachNewThreadSelector:@selector(updateThread) toTarget:self withObject:nil];

    UIImage *btnImage = [UIImage imageNamed:@"iPhone_General_Button_Add_Blog.png"];
    UIButton *viewBtnAddBlog = [UIButton buttonWithType:UIButtonTypeCustom];
    [viewBtnAddBlog setImage:btnImage forState:UIControlStateNormal];
    viewBtnAddBlog.frame = CGRectMake(0, 0, 80, 36);
    [viewBtnAddBlog addTarget:self action:@selector(addBlogByButton:) forControlEvents:UIControlEventTouchUpInside];

    UIBarButtonItem *btnAddBlog = [[UIBarButtonItem alloc] initWithCustomView:viewBtnAddBlog];
    btnAddBlog.tintColor = [UIColor clearColor];
    self.navigationItem.rightBarButtonItem = btnAddBlog;
}

Затем другие функции, которые используются для потоковой передачи:

/*
 Thread to update the progress bar with.
 */
- (void)updateThread
{
    @autoreleasepool {
        while(YES){
            [self performSelectorOnMainThread:@selector(updateProgressBar) withObject:nil waitUntilDone:false];
            [NSThread sleepForTimeInterval:0.1f];
        }
    }
}

/*
 Updates the progress bar.
 */
- (void)updateProgressBar
{
    pvProgress.progress = dProgress;
}

Если стоит упомянуть: я использую Xcode 4.2.1. Еще раз спасибо за поддержку!


person Tybs    schedule 17.01.2012    source источник


Ответы (3)


Прямо сейчас я просто хочу ударить себя камнем.

Я только что понял, что цикл "пока" никогда не останавливается. Конечно, это означает, что поток будет продолжать работать, поэтому память никогда не будет освобождена, пока приложение не завершит работу.

Просто добавив логическое значение, для которого установлено значение «НЕТ», когда поток должен завершиться, проблема была решена. Всем: большое спасибо за внимание к этой проблеме для меня. Иногда самые большие проблемы имеют самые маленькие решения...

person Tybs    schedule 18.01.2012
comment
да, верно :) но вы все равно можете почтить наши ответы 1-1 плюсом... :) - person ; 18.01.2012
comment
Готово, ребята, вы это заслужили :) - person Tybs; 21.01.2012

Блок @autoreleasepool входит в код вашего потока (в данном случае updateThread), а не вокруг создания потока.

person Rob Napier    schedule 17.01.2012
comment
Спасибо за ответ: но я должен ответить так же, как на H2CO3. К сожалению, это не решило проблему. Мой вопрос обновлен. - person Tybs; 18.01.2012

Вы не создаете пул автоматического выпуска внутри метода отдельного селектора. Каждому селектору потоков нужен свой собственный пул. Делайте так:

- (void) updateThread
{
    @autoreleasepool {
        // former code here
    }
}
person Community    schedule 17.01.2012
comment
Спасибо: я только что попробовал это, но, похоже, это не имеет никакого другого эффекта. Я обновил вопрос с дополнительной информацией. - person Tybs; 18.01.2012