Question

J'ai une classe qui met à jour deux fichiers .plist dans le répertoire des documents de l'application via un NSURLConnection. La classe agit en tant que son propre délégué pour NSURLConnection. Cela fonctionne correctement lorsque je demande un seul fichier, mais échoue lorsque je tente de mettre à jour deux fichiers. Est-ce qu'il me semble que je devrais créer un nouveau fil pour chacun des messages getNewDatabase?

- (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 ...
Était-ce utile?

La solution

J'ai trouvé quelque chose d'intéressant avec NSURLConnection et NSThread - le thread ne restera actif que le temps nécessaire à l'exécution de la méthode que vous appelez à partir de celui-ci.

Dans le cas ci-dessus, le thread ne vivra que tant que getNewDatabase: (NSString *) dbName a besoin d'être achevé, éliminant ainsi l'une de ses méthodes déléguées avant qu'il n'ait le temps de faire quoi que ce soit.

J'ai trouvé le site qui fournit une meilleure explication et une solution au problème

Je l'ai modifié un peu pour pouvoir créer un délai personnalisé s'il ne s'achève pas dans un laps de temps donné (pratique lorsque quelqu'un se promène entre deux 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;
    }
}

Autres conseils

Comme cela se trouve 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 autre chose 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, nous vous recommandons d'utiliser NSOperationQueue et NSOperation plutôt que de résoudre le problème avec le code actuel. Je pense que votre cas convient parfaitement à NSOperationQueue , d'autant plus que vous avez plusieurs tâches de téléchargement à effectuer.

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

Marcus Zarra a également rédigé un tutoriel montre à quel point il est facile d’intégrer et d’utiliser NSOperationQueue pour des opérations en arrière-plan simples.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top