Iphone: прохождение объектов и несколько потоков - PullRequest
1 голос
/ 29 сентября 2010

У меня возникли проблемы при передаче объекта NSNumber в другие потоки. Я вызываю функцию на viewDidload, которая загружает некоторые объекты из основных данных в качестве фонового процесса. которая вызывает другую функцию, которая просматривает загруженные объекты, чтобы увидеть, есть ли какие-либо изображения, связанные с ней, уже загруженные. если его нет, загрузите изображения асинхронно и сохраните его локально. Дело в том, что мне нужно выполнить startDownloadFor: atIndex: в главном потоке. Но приложение аварийно завершает работу из-за объекта NSNumber, который передается. вот код ..

- (void)viewDidLoad {
   ...
   ...
   [self performSelectorInBackground:@selector(loadImages) withObject:nil]; 
}

-(void)loadImages{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 ...
        ...
 [self fillInImages];
 [pool release];
}

-(void)fillInImages{

 NSString *imageURL;
 for (int i=0; i < [dataManager.objectList count]; i++) {
  ...
  if ([dataManager.RelatedImages Image] == nil) {
   //[self startDownloadFor:imageURL atIndex:[NSNumber numberWithInt:i]; // << WORKS FINE
   [self performSelectorOnMainThread:@selector(startDownloadFor:atIndex:) withObject:(imageURL, [NSNumber numberWithInt:i]) waitUntilDone:YES]; // << CRASHES 
   ...
  }else {
   ...
  }
  ...
 }
 ...
}

-(void)startDownloadFor:(NSString*)imageUrl atIndex:(int)indexPath{

 NSString *indexKey = [NSString stringWithFormat:@"key%d",indexPath];
 ...
}

как правильно это сделать?

Спасибо

Ответы [ 2 ]

1 голос
/ 29 сентября 2010

Вы пытаетесь передать 2 аргумента в performSelectorOnMainThread:withObject:waitUntilDone:, в то время как метод поддерживает передачу только одного аргумента.

Вам нужно использовать NSInvocation для отправки большего количества аргументов (или использовать NSDictionary, как предложил декан).

SEL theSelector;
NSMethodSignature *aSignature;
NSInvocation *anInvocation;

theSelector = @selector(startDownloadFor:atIndex:);
aSignature = [self instanceMethodSignatureForSelector:theSelector];
anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
[anInvocation setSelector:theSelector];
[anInvocation setTarget:self];
// indexes for arguments start at 2, 0 = self, 1 = _cmd
[anInvocation setArgument:&imageUrl atIndex:2];
[anInvocation setArgument:&i atIndex:3];

[anInvocation performSelectorOnMainThread:@selector(invoke) withObject:NULL waitUntilDone:YES];
1 голос
/ 29 сентября 2010

Я никогда не видел, чтобы синтаксис передавал более одного объекта селектору - это действительный код target-c? также, в вашем startDownloadFor: atIndex: вы передаете NSNumber, но тип для второго параметра в этом селекторе - (int) - это не может быть хорошим;)

Документы для executeSelectorOnMainThread : говорят, что селектор должен принимать только один аргумент типа id. Вы передаете недопустимый селектор, поэтому я думаю, что он очень запутан в том, где находится NSNumber.

Чтобы исправить это, передайте NSDictionary, содержащий число и URL-адрес изображения, т.е.

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:imageURL, @"imageURL", [NSNumber numberWithInt:i], @"number", nil];
[self performSelectorOnMainThread:@selector(startDownload:) withObject:dict waitUntilDone:YES];

и

//-(void)startDownloadFor:(NSString*)imageUrl atIndex:(int)indexPath{
- (void)startdownload:(NSDictionary *)dict {
    NSURL *imageURL = [dict objectForKey:@"imageURL"];
    int indexPath = [[dict objectforKey:@"number"] intValue];
...