2014-07-21 91 views
0

在这段代码片断中,程序流程首先变为 ,然后才进入块内部
resultBlock:^(ALAsset * asset)。 代码首先在底部打印NSLog,然后在循环内执行块。这里发生了什么事?程序流程出错

ALAssetsLibrary *lib=[ALAssetsLibrary new]; 
    _sizeOfSelectedImage=0; 
     for (int i=0; i<assets.count; i++) { 
      ALAsset *asset=assets[i]; 
      FileOP *fileMgr=[[FileOP alloc]init]; 
      NSString *baseDir=[fileMgr GetDocumentDirectory]; 

      //STORING FILE INTO LOCAL 

      [lib assetForURL:asset.defaultRepresentation.url 
       resultBlock:^(ALAsset *asset){ 
        ALAssetRepresentation *repr = [asset defaultRepresentation]; 
        CGImageRef cgImg = [repr fullResolutionImage]; 
        NSString *fname = repr.filename; 
        UIImage *img = [UIImage imageWithCGImage:cgImg]; 
        NSData *data = UIImagePNGRepresentation(img); 
        [data writeToFile:[baseDir stringByAppendingPathComponent:fname] 
          atomically:YES]; 
        //FOR LOCAL URL OF THE IMAGE 
        //NSString *imageURL = [baseDir stringByAppendingPathComponent:fname]; 
        //UIImage *myImg =[UIImage imageWithContentsOfFile:imageURL]; 
        //NSLog(@"%@ URL OF IMAGE ",imageURL); 
        NSLog(@"Image %d has %d size",i,data.length); 
        _sizeOfSelectedImage +=data.length; 
        NSLog(@"%d is the size",_sizeOfSelectedImage); 

       } 
          failureBlock:^(NSError *error){ 

       }]; 
     } 

     NSLog(@"COPIED %lu FILE INTO LOCAL MEMORY AND TOTAL SIZE COPIED IS %d ",(unsigned long)assets.count,_sizeOfSelectedImage); 
+0

我猜块是,它不会首先返回。 – klcjr89

+0

这是我的问题。我不知道为什么它在执行块之前会出现循环。然后再次返回到循环。我通过breapoints。程序进入for循环。就在块开始的地方,它不在循环之中。在底部打印NSLog。然后返回到循环。 –

+1

这就是它应该的方式。 – klcjr89

回答

3

方法assetForURL:resultBlock:failureBlock:将异步执行资产的加载。这就是为什么我们先执行底部的NSLog,然后再执行Block。如果你希望它被同步执行,像这样做:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) ^{ 
     ALAssetsLibrary *lib=[ALAssetsLibrary new]; 
     _sizeOfSelectedImage=0; 

     dispatch_group_t group = dispatch_group_create(); 

     for (int i=0;i<assets.count;i++) { 
       ALAsset *asset=assets[i]; 
       FileOP *fileMgr=[[FileOP alloc]init]; 
       NSString *baseDir=[fileMgr GetDocumentDirectory]; 

       //STORING FILE INTO LOCAL 
       dispatch_group_enter(group); 
       [lib assetForURL:asset.defaultRepresentation.url 
        resultBlock:^(ALAsset *asset){ 
         ALAssetRepresentation *repr = [asset defaultRepresentation]; 
         CGImageRef cgImg = [repr fullResolutionImage]; 
         NSString *fname = repr.filename; 
         UIImage *img = [UIImage imageWithCGImage:cgImg]; 
         NSData *data = UIImagePNGRepresentation(img); 
         [data writeToFile:[baseDir stringByAppendingPathComponent:fname] 
           atomically:YES]; 
         //FOR LOCAL URL OF THE IMAGE 
         //NSString *imageURL = [baseDir stringByAppendingPathComponent:fname]; 
         //UIImage *myImg =[UIImage imageWithContentsOfFile:imageURL]; 
         //NSLog(@"%@ URL OF IMAGE ",imageURL); 
         NSLog(@"Image %d has %d size",i,data.length); 
         _sizeOfSelectedImage +=data.length; 
         NSLog(@"%d is the size",_sizeOfSelectedImage); 
         dispatch_group_leave(group); 
        } 
        failureBlock:^(NSError *error){ 
           dispatch_group_leave(group); 
        }]; 
      } 
      dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 
      NSLog(@"COPIED %lu FILE INTO LOCAL MEMORY AND TOTAL SIZE COPIED IS %d ",(unsigned long)assets.count,_sizeOfSelectedImage); 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       // Do your call back on main thread here 
      }); 
    }); 

EDIT1:增强的答案从肯

ALAssetsLibrary *lib=[ALAssetsLibrary new]; 
_sizeOfSelectedImage=0; 

dispatch_group_t group = dispatch_group_create(); 

for (int i=0;i<assets.count;i++) { 
    ALAsset *asset=assets[i]; 
    FileOP *fileMgr=[[FileOP alloc]init]; 
    NSString *baseDir=[fileMgr GetDocumentDirectory]; 

    //STORING FILE INTO LOCAL 
    dispatch_group_enter(group); 
    [lib assetForURL:asset.defaultRepresentation.url 
     resultBlock:^(ALAsset *asset){ 
      ALAssetRepresentation *repr = [asset defaultRepresentation]; 
      CGImageRef cgImg = [repr fullResolutionImage]; 
      NSString *fname = repr.filename; 
      UIImage *img = [UIImage imageWithCGImage:cgImg]; 
      NSData *data = UIImagePNGRepresentation(img); 
      [data writeToFile:[baseDir stringByAppendingPathComponent:fname] 
        atomically:YES]; 
      //FOR LOCAL URL OF THE IMAGE 
      //NSString *imageURL = [baseDir stringByAppendingPathComponent:fname]; 
      //UIImage *myImg =[UIImage imageWithContentsOfFile:imageURL]; 
      //NSLog(@"%@ URL OF IMAGE ",imageURL); 
      NSLog(@"Image %d has %d size",i,data.length); 
      _sizeOfSelectedImage +=data.length; 
      NSLog(@"%d is the size",_sizeOfSelectedImage); 
      dispatch_group_leave(group); 
     } 
     failureBlock:^(NSError *error){ 
      dispatch_group_leave(group); 
     }]; 
} 
dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 
    // Do your call back on main thread here 
    NSLog(@"COPIED %lu FILE INTO LOCAL MEMORY AND TOTAL SIZE COPIED IS %d ",(unsigned long)assets.count,_sizeOfSelectedImage); 

    // Your code here 
}); 
+1

这是我第一个想法!如何使它同步和纠正任何想法的程序流程? –

+0

我试过了。它冻结了我的应用程序。 –

+2

不要尝试使异步方法同步。改变你的程序逻辑来处理ssynchronicity。在这种情况下,将最终日志放入结果块中。 –