2014-02-13 38 views
0

我想從框api獲取元數據,所以我需要遍歷整個目錄結構。下面是代碼:無限循環遍歷雲存儲文件結構[框api]

- (IBAction)ls { 

    // INITIALIZE folderID (will be nil only for the root folder) 

    if (self.folderID == nil) 
    { 
     self.folderID = BoxAPIFolderIDRoot; 
     self.folderName = @"Root"; 
    } 

    // START TRAVERSING DIRECTORY TREE 
    [self traverseItemsWithFolderID:self.folderID name:self.folderName]; 
    } 


- (void)traverseItemsWithFolderID:(NSString *)folder name:(NSString *)namefolder 

{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     [self fetchFolderItemsWithFolderID:folder name:namefolder]; // <- List Files/dirs in directory namefolder 

     dispatch_async(dispatch_get_main_queue(), ^{ 

    // Create box object "item" to traverse folderItemsArray 
    BoxItem * item = (BoxItem *)[self.folderItemsArray objectEnumerator]; 
    for (item in self.folderItemsArray) 
    { 
     if([item.type isEqualToString:BoxAPIItemTypeFolder]) 
      { 
       NSLog(@"SubFolder id %@", item.modelID); 
       NSLog(@"SubFolder name %@", item.name); 
       [self traverseItemsWithFolderID:item.modelID name:item.name]; 

      } 
    } 

    }); 
    }); 
} 

and this last method: 

- (void)fetchFolderItemsWithFolderID:(NSString *)innerFolder name:(NSString *)innerFolderName 
{ 

    BoxFoldersResourceManager *mgr = [BoxSDK sharedSDK].foldersManager; 
    BoxFoldersRequestBuilder *bldr = [[BoxFoldersRequestBuilder alloc] initWithQueryStringParameters:@{ @"fields" : @"name,type,id,etag,size,modified_at,hash" }]; 

    [mgr folderItemsWithID:innerFolder requestBuilder:bldr success: ^(BoxCollection *collection) 
    { 
     self.folderItemsArray = [NSMutableArray array]; 
     for (NSUInteger i = 0; i < collection.numberOfEntries; i++) 
     { 
      [self.folderItemsArray addObject:[collection modelAtIndex:i]]; 

      NSLog(@"FOLDER NAME %@", innerFolderName); 

      BoxItem *item = (BoxItem *)[self.folderItemsArray objectAtIndex:i]; 

       NSLog(@"Here The list of Files/Directories:"); 
       NSLog(@"TypE %@", item.type);     // [file/directory] 
       NSLog(@"NAME %@", item.name);     // filename 

       NSLog(@"ID %@", item.ETag);      // directory level [0 = root] 
       NSLog(@"ID %@", item.modelID);     // metadata unique identifier [FolderID !] 

       NSLog(@"SIZE %@", item.size);     // in bytes 
       NSLog(@"Modified Time %@", item.modifiedAt);  // in UTC format 

       NSLog(@"HASH %lu", (unsigned long)item.hash); // hash 
     } 
     self.totalCount = [collection.totalCount integerValue]; 
     NSLog(@" Number of files/dirs in Level %ld", (long)self.totalCount); 
    } 

最終的結果是,代碼開始請求的無限循環,不明白爲什麼,因爲當沒有更多的目錄,應立即停止。任何幫助確定問題非常感謝。

謝謝!

+0

哈希是不是由框返回的場API。它是NSObject上的方法哈希值:https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/ hash –

+0

感謝Ryan,你是絕對正確的:它不是來自BOX API(只是在代碼中有一個斷點進行了驗證)仍然...代碼崩潰,出現錯誤:「終止應用程序,由於未捕獲異常'NSGenericException',原因:'*** Collection <__ NSArrayM:0x8b8fbb0>在枚舉時發生了變化''「我的代碼並沒有真正起作用,因爲對於box中的每個目錄,都會觸發一個新任務來檢索目錄元數據,因爲使用了相同的唯一數組爲了存儲元數據,所有這些併發線程將最終覆蓋數組並導致崩潰 –

+0

第一個改進可能是爲遞歸方法提供兩個異步任務和一個完成處理程序:第一個改進是檢索當前目錄元數據w第二個(在第一個完成時啓動)將檢查目錄,然後爲每個目錄啓動遞歸方法。如果每個子目錄只有一個目錄,但是如果它具有多個目錄,則可以運行多個遞歸方法也會同時啓動。這最終會導致數組被覆蓋並且程序崩潰。 –

回答

0

您應該避免使用屬性self.folderItemsArray,因爲你有一個遞歸方法,試試這個:

- (NSArray*)fetchFolderItemsWithFolderID:(NSString *)innerFolder name:(NSString *)innerFolderName 
{ 
    ... 
     // This is a new line. 
     NSMutableArray* folderItemsArray = [NSMutableArray array]; 
     [mgr folderItemsWithID:innerFolder requestBuilder:bldr success: ^(BoxCollection *collection) 
    { 
    //self.folderItemsArray = [NSMutableArray array]; remove this line. 
    for (NSUInteger i = 0; i < collection.numberOfEntries; i++) 
    { 
     [folderItemsArray addObject:[collection modelAtIndex:i]]; // remove the self here. 
    ... 
    } 
    return folderItemsArray; 
} 

而且更新這樣這個方法:

- (void)traverseItemsWithFolderID:(NSString *)folder name:(NSString *)namefolder 

{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     NSArray* items = [self fetchFolderItemsWithFolderID:folder name:namefolder]; // <- List Files/dirs in directory namefolder 

     dispatch_async(dispatch_get_main_queue(), ^{ 

    // Create box object "item" to traverse folderItemsArray 
    //BoxItem * item = (BoxItem *)[self.folderItemsArray objectEnumerator]; why do you need this line. 
    for (BoxItem *item in items) 
    { 
     if([item.type isEqualToString:BoxAPIItemTypeFolder]) 
      { 
       NSLog(@"SubFolder id %@", item.modelID); 
       NSLog(@"SubFolder name %@", item.name); 
       [self traverseItemsWithFolderID:item.modelID name:item.name]; 

      } 
    } 

    }); 
    }); 
} 
+0

感謝您的回答,但實際上並不奏效:它停止在第一次迭代(根文件夾) –