Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 请求ALAssetRepresentation的size属性时代码被卡住_Ios_Iphone_Alassetslibrary_Alasset - Fatal编程技术网

Ios 请求ALAssetRepresentation的size属性时代码被卡住

Ios 请求ALAssetRepresentation的size属性时代码被卡住,ios,iphone,alassetslibrary,alasset,Ios,Iphone,Alassetslibrary,Alasset,我有一个方法返回一个集合的数据。我为一个又一个资产调用此方法,以从中获取NSData并将其上载到服务器。每4或5次调用后,代码就会在下面的rep.size调用中卡住。当我在XCode中暂停并恢复执行时,它会再次开始工作。我完全被难住了,任何帮助都将不胜感激 说明:死锁/代码卡在库代码中,而不是我的代码中 附加信息:我只有一个AlassetLibrary实例,我正在确保它没有被任何其他线程使用 +(void)getDataFromAssetURL:(NSString *) myImageURL o

我有一个方法返回一个集合的数据。我为一个又一个资产调用此方法,以从中获取NSData并将其上载到服务器。每4或5次调用后,代码就会在下面的rep.size调用中卡住。当我在XCode中暂停并恢复执行时,它会再次开始工作。我完全被难住了,任何帮助都将不胜感激

说明:死锁/代码卡在库代码中,而不是我的代码中

附加信息:我只有一个AlassetLibrary实例,我正在确保它没有被任何其他线程使用

+(void)getDataFromAssetURL:(NSString *) myImageURL ofType:(enum ImageType)imageType andPerformBlock:(NSDataBlock)block blocking:(BOOL)blocking
{
    NSConditionLock * albumReadLock = nil;
    if (blocking) {

        albumReadLock = [[NSConditionLock alloc] initWithCondition:PENDING];
    }
    @autoreleasepool {
        @try {

            NSURL *str = [[NSURL alloc] initWithString: myImageURL];

            ALAsset * asset = [[AppManager sharedInstance].assetObjectCache objectForKey:str];
            if (asset && NO) {
                block( [Util getDataFromAsset:asset ofType:imageType] );

                // notifies the lock that "all tasks are finished"
                [albumReadLock lock];
                [albumReadLock unlockWithCondition:ALLFINISHED];
            }
            else {
                ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
                {
                    @autoreleasepool {
                        @try {


                            [[AppManager sharedInstance].assetObjectCache setObject:myasset forKey:str];

                            NSData * assetData = [Util getDataFromAsset:myasset ofType:imageType];

                            block(assetData);

                            // notifies the lock that "all tasks are finished"
                            [albumReadLock lock];
                            [albumReadLock unlockWithCondition:ALLFINISHED];



                        }
                        @catch (NSException *exception) {
                            block(nil);
                            // important: notifies lock that "all tasks finished" (even though they failed)
                            [albumReadLock lock];
                            [albumReadLock unlockWithCondition:ALLFINISHED];
                        }
                        @finally {

                        }
                    }

                };

                ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
                {
                    block(nil);
                    // important: notifies lock that "all tasks finished" (even though they failed)
                    [albumReadLock lock];
                    [albumReadLock unlockWithCondition:ALLFINISHED];
                };



                if(str)
                {
                    NSURL *asseturl = str;

                    [[AppManager sharedInstance].assetslibrary assetForURL:asseturl
                                                               resultBlock:resultblock
                                                              failureBlock:failureblock];

                }
                else {
                    block(nil);
                    // notifies the lock that "all tasks are finished"
                    [albumReadLock lock];
                    [albumReadLock unlockWithCondition:ALLFINISHED];
                }
            }


        }
        @catch (NSException *exception) {
            block(nil);
            // notifies the lock that "all tasks are finished"
            [albumReadLock lock];
            [albumReadLock unlockWithCondition:ALLFINISHED];
        }
        @finally {

        }
    }

    if (blocking) {
        // non-busy wait for the asset read to finish (specifically until the condition is "all finished")
        [albumReadLock lockWhenCondition:ALLFINISHED];
        [albumReadLock unlock];

    }
}


+(NSData *)getDataFromAsset:(ALAsset *)myasset ofType:(enum ImageType)imageType
{
    ALAssetRepresentation *rep = [myasset defaultRepresentation];

    CGImageRef iref = nil;
    NSData *assetData = nil;

    if (imageType == FULL_RESOLUTION) {
        Byte *buffer = (Byte*)malloc(rep.size);
        NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
        assetData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
    }
    else if (imageType == LARGE_IMAGE){
        iref = [rep fullScreenImage];
        UIImage * uiimage = [UIImage imageWithCGImage:iref];
        ////NSLog(@"%f %f", uiimage.size.width, uiimage.size.height);
        assetData = UIImageJPEGRepresentation(uiimage, 1.0f);
    }
    else if (imageType == SQUARE_THUMB){
        iref = [myasset thumbnail];
        assetData = UIImageJPEGRepresentation([UIImage imageWithCGImage:iref], 1.0f);
    }
    else if (imageType == PERSPECTIVE_THUMB){
        iref = [myasset aspectRatioThumbnail];
        assetData = UIImageJPEGRepresentation([UIImage imageWithCGImage:iref], 1.0f);
    }

    return assetData;
}

新信息:原来问题只发生在特定的设备上。如上所述,如果我在XCode中暂停并取消暂停调试器,代码将向前移动。

如果您从主线程启动此代码块,则会导致ALAsset代码中出现死锁。您必须首先进入后台线程,因为AlassetLibrary需要能够在主线程上执行代码,如果主线程以您上面列出的方式被阻塞,那么它将永远等待执行。

我还不知道解决方案,但我知道这是一种非常神秘的方法。您需要研究GCD,它的主要目的之一是减少锁的头痛。它还可以使代码更加清晰,并获得更高级别的抽象。此外,如果您处于ARC环境中,则在大多数情况下不需要使用自动释放池。就调试死锁而言,请参见以下内容:正如我在问题中所解释的,死锁出现在iOS(ALAssetLibrary代码)中,而不是因为我使用的锁。我使用的锁只是为了使函数同步(不幸的是这是一个要求)。我正在更新这个问题,以便更清楚地说明死锁在ALAssetLibrary代码中。@try/@catch在Objective-C中的含义与在其他语言中的含义不同。简言之,它们只是一个更好的断言。您应该假设您的程序在捕获异常后处于损坏状态,唯一正确的做法是尽快中止该程序。您成功修复了它吗?@Devfly是和否。我用另一部iPhone测试了相同的代码,每次都能正常运行。然后我尝试了另一个示例应用程序,该应用程序在第一台iPhone上访问了ALAssetLibrary,并且每次都能重现这个问题。看起来那部iPhone的照片库已经损坏了。我重置了iPhone并恢复了照片库,从那以后就没有看到过问题。