在此代码段中,程序流向
 首先退出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);

最佳答案

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

关于ios - 程序流程出错,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24857150/

10-12 03:37