executeSelectorOnMainThread выдает сообщение об освобождении - PullRequest
2 голосов
/ 12 октября 2011

При разборе данных в твиттере я использовал потоки для вызова основного URL-адреса для загрузки данных.Это делает загрузку отлично, но когда я нажимаю кнопку «Назад» во время загрузки данных, он выбрасывает сообщение executeSelectorOnMainThread, которое освобождается.Я знаю, что мы можем использовать isCancelled, но он пока не работает для меня.Кто-нибудь сталкивался с этой проблемой и решил ее.

- (void)LoadTwitterData
{
NSString *urlString =@"http://search.twitter.com/search.json?q=tabc&result_type=recent&rpp=2500";
NSURL *url = [NSURL URLWithString:urlString];

NSString *jsonString = [NSString stringWithContentsOfURL:url];
NSDictionary *values = [jsonString JSONValue];    

/**** Throws here *****/
[self performSelectorOnMainThread:@selector(didFinishLoadingResults:) withObject:values waitUntilDone:NO];

}

Ответы [ 2 ]

2 голосов
/ 12 октября 2011

Если вы раскручиваете поток с помощью селектора на self, вам необходимо убедиться, что self сохраняется на время этого потока, в противном случае (как в вашем случае) self может быть освобождено, и ваш нить попробует перезвонить в зомби. Самый простой способ сделать это - передать self потоку в качестве аргумента. Если вы используете performSelectorInBackground:withObject:, вы должны сделать что-то вроде этого:

[self performSelectorInBackground:@selector(LoadTwitterData) withObject:self];

Или, если вы используете NSThread, вы должны передать self аргументу object: инициализатора.

На самом деле самый безопасный способ использования потоковых методов - это сделать метод статическим:

+ (void)LoadTwitterData:(id)arg
{
    // ...
    MyController *self = arg;

    // ... do work

    [self performSelectorOnMainThread:@selector(didFinishLoadingResults:)
                           withObject:values waitUntilDone:NO];

}

Таким образом, вы не можете случайно получить доступ к переменным экземпляра, что позволяет избежать различных проблем с многопоточностью. Любые данные, которые нужны потоку, включая self для обратного вызова, должны передаваться как 'arg', который может быть массивом или словарем или чем угодно, что вам нужно. Таким образом, вы знаете, что все, что нужно потоку, будет сохранено на время потока, а поскольку вы не обращаетесь к переменным экземпляра через self, другой поток не может перейти и изменить их под вами.

Еще одна вещь, которую вы должны сделать в методе потоков - это обернуть все это пулом авто-релиза:

- (void)LoadTwitterData
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    @try {
        // ...
    } @finally {
        [pool drain];
    }
}
0 голосов
/ 12 октября 2011

Если LoadTwitterData: находится в фоновом потоке, вам нужно создать пул автоматического выпуска (если вы еще этого не сделали). Окружите свой код с помощью -

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];


//your code

[pool drain];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...