2009-08-01 6 views
3

J'ai une classe qui met à jour deux fichiers .plist dans le répertoire des documents de l'application via une connexion NSURLConnection. La classe agit comme son propre délégué pour NSURLConnection. Cela fonctionne correctement lorsque je demande un seul fichier, mais échoue lorsque j'essaie de mettre à jour deux fichiers. Est-ce que je devrais commencer un nouveau thread pour chacun des messages getNewDatabase?NSURLConnection de délégation et threading - iPhone

- (void)getAllNewDatabases { 
    [self performSelectorOnMainThread:@selector(getNewDatabase:) withObject:@"file1" waitUntilDone:YES]; 
    [self performSelectorOnMainThread:@selector(getNewDatabase:) withObject:@"file2" waitUntilDone:YES]; 
} 

- (BOOL)getNewDatabase:(NSString *)dbName 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSMutableString *apiString = [[NSMutableString alloc] initWithString:kAPIHost]; 
    [apiString appendFormat:@"/%@.plist",dbName]; 
    NSURLRequest *myRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:apiString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; 
    NSURLConnection *myConnection = [[NSURLConnection alloc] initWithRequest:myRequest delegate:self]; 
    [apiString release]; 
    if(myConnection) 
    { 
     //omitted for clarity here 
    } 
    [pool release]; 
} 
//NSURLConnection delegate methods here ... 

Répondre

8

J'ai trouvé quelque chose d'intéressant avec NSURLConnection et NSThread - le fil ne vivra aussi longtemps que nécessaire pour effectuer la méthode que vous appelez de celui-ci.

Dans le cas ci-dessus le thread ne vivra que tant que getNewDatabase:(NSString *)dbName prend pour compléter, donc tuer toutes ses méthodes de délégué avant qu'ils aient le temps de faire quoi que ce soit.

Je trouve le site this qui donne une meilleure explication et une solution au problème

Je peaufiné un peu pour que je puisse avoir un temps personnalisé si elle n'a pas terminé dans un laps de temps donné (à portée de main quand quelqu'un se promène entre les points d'accès)

start = [NSDate dateWithTimeIntervalSinceNow:3]; 

    while(!isFinished && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
                beforeDate:[NSDate distantFuture]]){ 

    if([start compare:[NSDate date]] == NSOrderedAscending){ 
     isFinished = YES; 
    } 
} 
+1

Le blog que vous liez a été déplacé - Je crois que c'est ça: http://www.sortedbits.com/nsurlconnection-in-its-own-thread –

4

Comme il est actuellement dans le code que vous avez fourni, getNewDatabase: est en cours d'exécution sur le thread principal de votre application. Le problème dans ce cas particulier est alors quelque chose d'autre que le cycle de vie du fil, comme James l'a observé dans son cas.

Si vous aviez l'intention d'effectuer cette opération en arrière-plan, je vous recommande d'utiliser NSOperationQueue et NSOperation plutôt que de résoudre le problème avec le code actuel. Je pense que votre cas est un bon ajustement pour NSOperationQueue, d'autant plus que vous avez plus d'une tâche de téléchargement à effectuer.

Dave Dribin a un excellent article sur l'utilisation de l'API asynchrone, tel que NSURLConnection, à l'intérieur d'un NSOperation. Sinon, tant que vous exécutez un thread d'arrière-plan, vous pouvez également simplifier le processus et utiliser simplement une méthode d'API synchrone à la place dans votre NSOperation, par exemple initWithContentsOfURL:.

Marcus Zarra a également written a tutorial qui démontre à quel point il est facile d'incorporer et d'utiliser NSOperationQueue pour des opérations d'arrière-plan simples.

+0

Merci - en attendant - j'ai fourchu une version qui fait exactement cela avec NSOperation/NSOperationQueue. Fonctionne parfaitement maintenant. – FluffulousChimp