2012-07-12 20 views
5

जब मैं ALAssetsLibrary का उपयोग स्थानीय लोगों के लिए बनाए यह ठीक काम करता है की गलत संख्या वापस जाने के लिए लगता है। लेकिन जब मैं 'फोटो' एप्लिकेशन के साथ कुछ तस्वीरें हटा देता हूं तो मेरा ऐप दुर्घटनाग्रस्त हो जाता है।ALAssetsLibrary मेरी तस्वीर

क्रैश जानकारी है:

"Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSOrderedSet enumerateObjectsAtIndexes:options:usingBlock:]: index 14 beyond bounds [0 .. 9]'".'14'

यह स्थानीय फ़ोटो की संख्या की तरह दिखता है अभी भी befoore के रूप में ही रहता है। और जब भी मैं अपना ऐप छोड़ देता हूं और फिर से इसे पुनरारंभ करता हूं, तब भी यह दुर्घटनाग्रस्त हो जाता है।

स्थानीय तस्वीर एक्सेस कोड:

dispatch_async(dispatch_get_main_queue(),^
{ 
    @autoreleasepool 
    { 
     ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror) 
     { 
      NSLog(@"error occour =%@", [myerror localizedDescription]); 
     }; 

     ALAssetsGroupEnumerationResultsBlock groupEnumerAtion = ^(ALAsset *result, NSUInteger index, BOOL *stop) 
     { 
      if (result!=NULL) 
      { 
       if ([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) 
       { 
        [self.g_imageArray addObject:result]; 
       } 
      } 
     }; 

     ALAssetsLibraryGroupsEnumerationResultsBlock 
     libraryGroupsEnumeration = ^(ALAssetsGroup* group, BOOL* stop) 
     { 
      if (group == nil) 
      { 
       return; 
      } 

      if (group!=nil) { 
       [group enumerateAssetsUsingBlock:groupEnumerAtion]; 
      } 
     [self updatephotoList]; 
     }; 

     self.library = [[ALAssetsLibrary alloc] init]; 
     [self.library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos 
           usingBlock:libraryGroupsEnumeration 
          failureBlock:failureblock]; 
    } 
}); 

अगर मैं प्रणाली कैमरा के साथ एक और तस्वीर ले, अपने आवेदन पुनः ठीक करता है।

+0

एक सवाल: क्या आप यह सुनिश्चित करें कि '[आत्म updatephotoList]' '[समूह enumerateAssetsUsingBlock के अंतिम गणना ब्लॉक _after_ कॉल कर लिया जाएगा ... ] '? मेरे ऐप में दर्जनों दुर्घटनाएं हैं इसलिए मैं इस दृष्टिकोण की जांच करूंगा और देख सकता हूं कि यह कैसे काम करता है: http://stackoverflow.com/a/23378441/649379 – SoftDesigner

उत्तर

2

ऐसा लगता है कि यह एक आईओएस बग है, जैसा कि आपने कहा था कि एलासेट्स लाइब्रेरी ने आपकी तस्वीरों की गलत संख्या लौटा दी है, इसलिए आपको सीमाएं त्रुटि से बाहर सूचकांक मिला है। वैकल्पिक हल इस तरह फिर से आपकी फोटो को फिर से लोड करने के लिए है:

ALAssetsLibraryGroupsEnumerationResultsBlock 
libraryGroupsEnumeration = ^(ALAssetsGroup* group, BOOL* stop) 
{ 
     if (group == nil) 
     { 
      return; 
     } 
     //Force to reload photo as numberOfAssets is broken 
     NSLog(@"how many picture I have in this group: %d",[group numberOfAssets]); 
     [group setAssetsFilter:[ALAssetsFilter allPhotos]];//this will cause group to reload 
     NSLog(@"how many picture I have in this group: %d",[group numberOfAssets]); 

     if (group!=nil) { 
      [group enumerateAssetsUsingBlock:groupEnumerAtion]; 
     } 
    [self updatephotoList]; 
}; 
+0

आपकी मदद के लिए धन्यवाद – zhangwx

0

आप ALAssetsLibraryChangedNotification के लिए एक पर्यवेक्षक रजिस्टर पुस्तकालय परिवर्तन प्राप्त करने के लिए है करने की जरूरत है। जब अधिसूचना आग लगती है, तो AssetsLibrary के समूहों और सामग्री को पुन: उत्पन्न करें। यदि आप अधिसूचना के लिए पंजीकरण नहीं करते हैं तो आपके आवेदन को लाइब्रेरी का पुराना स्नैपशॉट मिलेगा और गणना विफल हो जाएगी। कृपया ध्यान दें वहाँ के रूप में यहाँ प्रलेखित आईओएस 5.x तहत ALAssetsLibraryChangedNotification के बारे में एक बग है कि: http://www.openradar.me/10484334

+0

यदि आप वर्तमान में देख रहे एल्बम को हटा चुके हैं तो आपकी सहायता नहीं होगी। हां, आपको एक अधिसूचना प्राप्त होगी, लेकिन ऐप फिर से गणना करने की कोशिश करते समय 'NSRangeException' अपवाद के साथ क्रैश हो जाएगा। –

+0

पृष्ठभूमि के बिना भी आईओएस 8 (जीएम) पर 'numberOfAssets' गलत हो सकता है। – Rivera

+0

हाँ, यह एक बग है। दुर्भाग्यवश संख्याऑफएसेट्स में आईओएस 8 (जीएम) – holtmann

1

एक पर्यवेक्षक का पंजीयन मेरे मामले में मदद नहीं की। उपयोगकर्ता अभी भी दुर्घटनाग्रस्त थे, लेकिन मैंने नहीं किया। आज तक।

मैं इस दुर्घटना को हल करने के तरीका खोज निकाला। अंत में ऐप्पल की फोटो लाइब्रेरी में यह एक बग है, लेकिन एक कामकाज है। आप क्या करते हैं, आप फ़िल्टर को फोटो पर सेट करते हैं, और उसके बाद वीडियो को डिफ़ॉल्ट 'संपत्ति' पर छोड़ने के बजाय। इसके बाद आप प्रत्येक के लिए एक बार गणना करते हैं, और यह सुनिश्चित करने के लिए कुछ चालबाजी करें कि आपको जो भी अपडेट चाहिए, उसे करने के लिए आपको अंतिम 'शून्य' बिंदु प्राप्त करें। मेरा वर्तमान दृष्टिकोण थोड़ा गन्दा है लेकिन आपको यह विचार मिलता है:

// pending is used to tell the block we're not done, even if result is NULL 
BOOL pending = YES; 
// resorted is just a flag I use in case there are no videos; if there are none, the block is never called at all, and thus the == NULL part never triggers 
__block BOOL resorted = NO; 

ALAssetsGroupEnumerationResultsBlock assetEnumerator = ^(ALAsset *result, NSUInteger index, BOOL *stop) { 
    if(result != NULL) { 
     [assets addObject:result]; 
    } else if (! pending) { 
     // ready!! 
     resorted = YES; 
     [self resort]; // my own method; replace with e.g. tableView reload! 
    } 
}; 

// there are two types of assets - photos and videos; we start with photo 
[group setAssetsFilter:[ALAssetsFilter allPhotos]]; 
NSLog(@"assets = %d", group.numberOfAssets); 
[group enumerateAssetsUsingBlock:assetEnumerator]; 
// we then set pending to NO; even though the enumeration happens in a separate thread, it seems like pending is not caught by the above enumeration (I have 105 images in the group I am enumerating, FWIW; it may be better to set pending in the == NULL part of the enumeration though 
pending = NO; 
// now we switch to video and do the same thing 
[group setAssetsFilter:[ALAssetsFilter allVideos]]; 
BriefLog(@"assets = %d", group.numberOfAssets); 
[group enumerateAssetsUsingBlock:assetEnumerator]; 

// if there are 0 vids, the above block is not ever called so we flip to a background thread and then back (probably not necessary) and then check if resorted is set; if it isn't we call resort 
if (! resorted) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     if (! resorted) { 
      [self resort]; // my own method; replace with e.g. tableView reload! 
     } 
    }); 
}); 

यही है। NSRangeExceptions चले जाओ। कम से कम मेरे मामले में उन्होंने किया।

+1

आपका 'लंबित = नहीं; 'का कोई प्रभाव नहीं है। ब्लॉक गैर-'__block' स्थानीय चर को उस समय मूल्य के आधार पर कैप्चर करते हैं जब वे बनाए जाते हैं। – user102008

+0

मुझे पूरा यकीन है कि कॉल में से एक को हां मिला और दूसरा नंबर मिला। जांच दो बार करना होगा। – Kalle

0

मैं Qiulang जवाब के साथ बाहर शुरू कर दिया है, लेकिन यह मेरे लिए काम नहीं किया। मेरे लिए क्या काम किया गया है, गणना शुरू करने से पहले, सभी फ़िल्टर संयोजनों के साथ setAssetsFilter को लगातार 3 बार कॉल करना है।

[group setAssetsFilter:[ALAssetsFilter allPhotos]]; 
[group setAssetsFilter:[ALAssetsFilter allVideos]]; 
[group setAssetsFilter:[ALAssetsFilter allAssets]]; 
+0

यह भी नहीं है या कॉल के बीच 'नंबरऑफएसेट्स' जोड़ने के लिए उचित फोटो गणना प्राप्त करने के लिए मेरे लिए काम किया है। – Rivera

0

iOS 8 में मैं यह भी देखा कि numberOfAssets रिटर्न फ़ोटो की गलत संख्या है, तो उनमें से कुछ को नष्ट कर दिया और वर्तमान में 'हाल ही में हटाए' एल्बम में स्थित थे।

+1

वास्तव में कोई जवाब नहीं बल्कि एक टिप्पणी। – Rivera

+0

मुझे एक ही समस्या थी, आईओएस 8.0.2 – Ponf

+0

में तय किया गया था मेरे लिए, नंबरऑफएसेट अभी भी आईओएस 8.0.2 पर गलत है – SarpErdag

0

आप में से जो लोग सब ALAssetRepresentations के साथ कुछ NSArray भरने और बहुत अधिक आप कोड को बदलने के लिए नहीं करना चाहते हैं के लिए, बस इस परीक्षक के साथ अपने सरणी को फ़िल्टर - AssetURLChecker

चीयर्स!

0

ALAssetsLibrary पुस्तकालय PHAssetsLibrary पर depriciated है इसलिए इस कोड का उपयोग:

__block PHAssetCollection *collection; 
    _arr_downloadedWallpaper = [[NSMutableArray alloc] init]; 

    // Find the album 
    PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init]; 
    fetchOptions.predicate = [NSPredicate predicateWithFormat:@"title = %@", @"Bhakti Ras"]; 
    collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum 
                  subtype:PHAssetCollectionSubtypeAny 
                  options:fetchOptions].firstObject; 

    PHFetchResult *collectionResult = [PHAsset fetchAssetsInAssetCollection:collection options:nil]; 

    [collectionResult enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) { 

     //add assets to an array for later use in the uicollectionviewcell 
     NSLog(@"asset is =%@",asset); 


     if (asset) { 
      [self.arr_downloadedWallpaper addObject:asset]; 
     } 
    }]; 
संबंधित मुद्दे