2011-11-26 46 views
1

這是從ALAssetsLibrary加載圖像的靜態函數。如何在IOS5上使用NSConditionLock

它在IOS4.X上運行良好,但是在IOS5上它將停在行: 「[albumReadLock lockWhenCondition:WDASSETURL_ALLFINISHED];」

如何在IOS4.x和iOS5上使用NSConditionLock?

// 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

使用dispatch_semaphore_t代替NSConditionLock

2

晚的答案,但我找到解決問題的辦法。請檢查以下代碼,我已更改導致崩潰的以下代碼行的位置。

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