程序流程出错了

时间:2014-07-21 03:03:35

标签: ios objective-c objective-c-blocks

在此代码段中,程序流程将继续  首先离开for循环然后只进入块内 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);

1 个答案:

答案 0 :(得分: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:来自Ken的强化答案

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
});