Как использовать NSConditionLock на IOS5 - PullRequest
1 голос
/ 26 ноября 2011

Это статическая функция для загрузки изображения из ALAssetsLibrary.

Хорошо работает на IOS4.X, но на IOS5 остановится на линии: "[albumReadLock lockWhenCondition: WDASSETURL_ALLFINISHED];"

Как использовать NSConditionLock как на IOS4.x, так и на iOS5?

// loads the data for the default representation from the ALAssetLibrary
+ (UIImage *) loadImageFromLibrary:(NSURL *)assetURL {
    static NSConditionLock* albumReadLock;
    static UIImage *realImage;

    // this method *cannot* be called on the main thread as ALAssetLibrary needs to run some code on the main thread and this will deadlock your app if you block the main thread...
    // don't ignore this assert!!
    NSAssert(![NSThread isMainThread], @"can't be called on the main thread due to ALAssetLibrary limitations");

    // sets up a condition lock with "pending reads"
    albumReadLock = [[NSConditionLock alloc] initWithCondition:WDASSETURL_PENDINGREADS];

    // the result block
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset) {
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        //NSNumber *orientation = [myasset valueForProperty:ALAssetPropertyOrientation];
        CGImageRef iref = [rep fullResolutionImage];
        NSNumber *orientation = [myasset valueForProperty:ALAssetPropertyOrientation];
        UIImage *image = [UIImage imageWithCGImage:iref scale:1.0 orientation:[orientation intValue]];
        realImage = [image retain];

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

    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        //NSLog(@"NOT GOT ASSET"); 
        //NSLog(@"Error '%@' getting asset from library", [myerror localizedDescription]);

        // important: notifies lock that "all tasks finished" (even though they failed)
        [albumReadLock lock];
        [albumReadLock unlockWithCondition:WDASSETURL_ALLFINISHED];
    };

    // schedules the asset read
    ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease];

    [assetslibrary assetForURL:assetURL
               resultBlock:resultblock
              failureBlock:failureblock];

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

    // cleanup
    [albumReadLock release];
    albumReadLock = nil;

    // returns the image data, or nil if it failed
    return realImage;
}

Ответы [ 2 ]

2 голосов
/ 03 февраля 2012

Поздний ответ Но я нашел решение проблемы. Проверьте следующий код, для которого я изменил место следующих строк кода, которые вызывали сбой.

 ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
        albumReadLock = [[NSConditionLock alloc] initWithCondition:0];
        // non-busy wait for the asset read to finish (specifically until the condition  is "all finished")
        [albumReadLock lockWhenCondition:1];
        [albumReadLock unlock];

============================== Ниже приведен весь код ======= ==============================

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
 {
   if(info)
      {
            // Don't pay any attention if somehow someone picked something besides an image.
      if([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeImage]){
    //           UIImageView *imageView1=[[UIImageView alloc]init];                                      // = (UIImageView *)self.view;

        // Hand on to the asset URL for the picked photo..
        self.imageURL = [info objectForKey:UIImagePickerControllerReferenceURL];
        // To get an asset library reference we need an instance of the asset library.
        static NSConditionLock* albumReadLock;

        // sets up a condition lock with "pending reads"
        ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
        albumReadLock = [[NSConditionLock alloc] initWithCondition:0];
        // non-busy wait for the asset read to finish (specifically until the condition is "all finished")
        [albumReadLock lockWhenCondition:1];
        [albumReadLock unlock];
        NSString *osVersion = [[UIDevice currentDevice] systemVersion];
        NSString *versionWithoutRotation = @"5.0";
        BOOL noRotationNeeded = ([versionWithoutRotation compare:osVersion options:NSNumericSearch] 
                                 != NSOrderedDescending);
        // The assetForURL: method of the assets library needs a block for success and
        // one for failure. The resultsBlock is used for the success case.


        ALAssetsLibraryAssetForURLResultBlock resultsBlock = ^(ALAsset *asset) 
        {
            ALAssetRepresentation *representation = [asset defaultRepresentation];
            CGImageRef image = [representation fullScreenImage];
            if(noRotationNeeded)
            {
                // Create a UIImage from the full screen image. The full screen image
                // is already scaled and oriented properly.
                imageView.image = [UIImage imageWithCGImage:image];
            }
            else
            {
                // prior to iOS 5.0, the screen image needed to be rotated so
                // make sure that the UIImage we create from the CG image has the appropriate
                // orientation, based on the EXIF data from the image.
                ALAssetOrientation orientation = [representation orientation];
                imageView.image = [UIImage imageWithCGImage:image scale:1.0 
                                                orientation:(UIImageOrientation)orientation];
            }
            [albumReadLock lock];
            [albumReadLock unlockWithCondition:1];
             [picker dismissModalViewControllerAnimated:YES];
        };
        ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error)
        {
            NSLog(@"FAILED! due to error in domain %@ with error code %d", error.domain, error.code);
            // This sample will abort since a shipping product MUST do something besides logging a
            // message. A real app needs to inform the user appropriately.
            [albumReadLock lock];
            [albumReadLock unlockWithCondition:1];
             [picker dismissModalViewControllerAnimated:YES];
            abort();
        };
        // Get the asset for the asset URL to create a screen image.
        [assetsLibrary assetForURL:self.imageURL resultBlock:resultsBlock failureBlock:failureBlock];
        // Release the assets library now that we are done with it.
        [assetsLibrary release];
    }
}
 }
2 голосов
/ 16 декабря 2011

Использование dispatch_semaphore_t вместо NSConditionLock

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...