2016-12-02 1 views
1

J'ai ajouté des ressources à la demande à mon application et les ai affichées sur l'App Store. Une partie de mes utilisateurs a des problèmes, un block completionHandler appelé lorsque les ressources ont fini le téléchargement ne se produit pas. Il ne dépend pas de l'espace disque. Dans la plupart des cas, cela fonctionne correctement. Une fois que j'ai le même truoble, je réinitialise le contenu de mon iPhone, réinstalle l'app, et le problème est laissé.Ressources ios à la demande certains utilisateurs ne fonctionnent pas

- (void) viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
      NSSet *tags = [NSSet setWithObjects: self.exerciseId, nil]; 
      resourceRequest = [[NSBundleResourceRequest alloc] initWithTags:tags]; 
      [resourceRequest conditionallyBeginAccessingResourcesWithCompletionHandler: 
       ^(BOOL resourcesAvailable) 
       { 

        if (resourcesAvailable) { 
         dispatch_async(dispatch_get_main_queue(), ^{ 
          [self setupMoviePlayerVideoWithName:_exerciseId]; 
         }); 
        } 
        else { 
         [self tryToGetODR]; 
        } 
       }];  
} 


    -(void) tryToGetODR{ 
      resourceRequest.loadingPriority = NSBundleResourceRequestLoadingPriorityUrgent; 
      [resourceRequest beginAccessingResourcesWithCompletionHandler: ^(NSError * __nullable error){ 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         if (error) { 

          return; 
         } 
         [self.videoImageView setHidden:true]; 
         [self.activityIndikator setHidden:true]; 
         [self.downloadProgressLabel setHidden:true]; 
         [self setupMoviePlayerVideoWithName:_exerciseId]; 

        }); 
       }]; 
    } 

Quelqu'un a-t-il été confronté à un problème similaire?

+0

Afficher le code réel, s'il vous plaît. – matt

+0

@matt Je l'ai fait, merci – Ivan

+0

Merci! Alors dites-vous que "tryToGetODR" n'est jamais appelé? Ou dites-vous qu'il est appelé mais les quatre dernières lignes (le gestionnaire d'achèvement) ne sont jamais exécutées? – matt

Répondre

0

La nature sporadique du problème suggère immédiatement un problème de filetage. Et en effet, vous en avez un. Changer:

else { 
    [self tryToGetODR]; 
} 

à:

else { 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self tryToGetODR]; 
    }); 
} 

Sinon (entre autres mauvaises choses) que vous essayez d'accéder resourceRequest et lancer l'accès non conditionnel à un fil d'arrière-plan. Cela signifie que vous ne donnez pas une chance à la première requête (la requête conditionnelle).

+0

Merci beaucoup! Je l'essaie, mais je ne comprends pas ce que vous vouliez dire "Sinon (entre autres mauvaises choses) vous essayez d'accéder à resourceRequest et de lancer l'accès non-conditionnel sur un thread d'arrière-plan. (la demande conditionnelle) une chance de compléter. " Pourriez-vous expliquer s'il vous plaît – Ivan

+0

concrètement pourquoi la première demande n'a pas une chance de compléter? – Ivan

+0

Vous appelez effectivement 'beginAccessingResourcesWithCompletionHandler' de _inside_' conditionallyBeginAccessingResourcesWithCompletionHandler'. Le gestionnaire d'achèvement n'est donc pas encore retourné et vous essayez de démarrer une nouvelle requête. Cela ne va pas nécessairement marcher. La documentation est assez claire à ce sujet! - De plus, vous parlez maintenant à une propriété d'instance de deux threads différents simultanément, ce qui est toujours une mauvaise idée. – matt