NSThread вылетает при втором вызове (iPhone) - PullRequest
2 голосов
/ 03 февраля 2009

У меня есть объект, и в этом объекте я запускаю свой поток (для загрузки выполняю некоторую загрузку URL).

Когда мне возвращают мои данные, я вызываю селектор для выполнения в главном потоке.

Работает нормально, если я звоню в первый раз, но во второй раз происходит сбой (без конкретной ошибки).

[NSThread detachNewThreadSelector:@selector(doThread:)
                         toTarget:self
                       withObject:@"lala"];

-(void) doThread:(NSString *)poststring {
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


DataModelLocator *mydelegate = [DataModelLocator instance];
NSData *postData = [poststring dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSURL *url = [NSURL URLWithString:[mydelegate fwaservicepath]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

[request setURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
[request setHTTPBody:postData];

NSURLResponse *urlResponse;

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:nil];

if(data) {
    [self performSelectorOnMainThread:@selector(loadDidFinishWithData:)
                           withObject:data 
                        waitUntilDone:YES];
    //[self loadDidFinishWithData:data];
} else {
    [self performSelectorOnMainThread:@selector(loadDidFinishWithError:)
                           withObject:data 
                        waitUntilDone:YES];
}
[pool release];

}
}

Он падает, когда я звоню performSelectorOnMaintThread ... Может быть, он падает на синглтоне, когда его выпускают?

Ответы [ 2 ]

4 голосов
/ 03 февраля 2009

При работе с потоками избегайте автоматически выпущенных объектов, таких как чума. Автозапускные пулы будут сливаться в недетерминированное время, вызывая забавные сбои. Используйте alloc / init и release для всех задействованных объектов, убедившись, что сохранены все объекты, которые вы используете для методов, которые вызываются из другого потока с помощью executeSelectorOnMainThread или detachNewThreadSelector.

Сборка мусора на Mac эффективно решает эти проблемы, но в ближайшее время у iPhone этого не будет.

0 голосов
/ 03 февраля 2009

Возможно, вы захотите опубликовать более подробную информацию о вашей проблеме (какая из двух строк дает сбой, что вы выяснили из отладки до сих пор и т. Д.), Чтобы мы могли предложить вам несколько лучших предложений. Не зная, какая строка вызывает у вас проблемы, я рискну догадаться: по звуку у вас может быть объект, который очищается автоматической сборкой мусора.

Откуда берется переменная data? Если вы создаете его в заголовочном файле как личную переменную-член, у вас может быть что-то вроде:

NSSomeType *data = [NSSomeType builtInInitFunction];

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

// Objects initialized with init are retained
NSSomeType *data = [[NSSomeType alloc] init];

// Objects that would normally be autoreleased can be marked as retain
NSSomeType *data = [[NSSomeType builtInInitFunction] retain];

Я не уверен, как структурирован ваш код, но обязательно добавьте хотя бы один выпуск для каждого retain и init! Я все еще довольно плохо знаком с Objective-C, так что он немного похож на слепого, ведущего слепого, так что прими мой совет с долей соли.

Ознакомьтесь с разделом «Подробнее об управлении памятью» в Дополнительные сведения см. В Objective-C .

EDIT2: уточненный пример кода. Спасибо Эвану (комментарии) за помощь.

EDIT3: я согласен с Брэдом. Подумайте об удалении пула AutoRelease, который у вас есть для обработки вашего alloc / init / release. Я не знаю достаточно об объекте NSURLConnection, чтобы знать это, но помечена ли ваша * память данных как Autorelease? Если это так, вам может потребоваться инициализация другим способом или использование сохранения.

Шаг через ваш код в отладчике Выясните, A), какая именно строка вызывает сбой, а затем B) значения всех ваших переменных. Если вам повезет, вы заметите, что один - ноль.

...