2015-09-10 59 views
0

目前我正在開發一個Objective-c/Cocoa應用程序,該應用程序在其他文檔中查找圖像。不過,我在分析NSData時遇到了問題,因爲一段時間後NSData變爲空。下面是創建NSData的代碼,獲取長度和一些基本的調試。NSData在一段時間後變爲空

/* Get Data */ 
NSError *error; 
NSData *data = [NSData dataWithContentsOfFile:file options:NSDataReadingMapped error:&error]; 

/* Split Data into hex chunks */ 
/* Get length of data */ 
NSUInteger data_length = [data length]; 

/* Debug NSLogs */ 
NSLog(@"[1] Data length: %lu",(unsigned long)data_length); 
NSLog(@"[1] Data: %@ with Error: %@",data,error); 

當我NSLog的數據在這裏已傳遞被寫入其十六進制表示控制檯文檔。

但是,當我嘗試處理數據時,調試NSLog最後說數據爲空。 (用於十六進制FF for循環檢查數據)的代碼是下面:

/* Declare start and end pointer */ 
NSUInteger start_point = data_length + 2; 
NSUInteger end_pointer = data_length + 2; 

/* loop through data */ 
for (NSUInteger i = 0; i < data_length; i++) { 
    // Create Range 
    NSRange range = NSMakeRange(i, (i+1)); 
    // Allocate Byte 
    Byte byte[1]; 
    // Get data from data set 
    [data getBytes:byte range:range]; 
    // Convert Byte (char representation) to NSData 
    NSData *byte_data = [NSData dataWithBytes:byte length:1]; 
    // Set string representation of temp_data 
    NSString *byte_check = [NSString stringWithFormat:@"%@",byte_data]; 
    // Check Byte 
    if ([byte_check isEqualToString:@"<FF>"]) { 
     // First byte found, check if next is correct 
     NSRange range2 = NSMakeRange((i+1), (i+2)); 
     Byte byte2[1]; 
     [data getBytes:byte2 range:range2]; 
     NSData *byte_data2 = [NSData dataWithBytes:byte2 length:1]; 
     NSString *byte_check2 = [NSString stringWithFormat:@"%@",byte_data2]; 
     if ([byte_check2 isEqualToString:@"<E0>"]) { 
      // Success found start of JPEG 
      start_point = i; 
      // set i to length + 1 to stop loop 
      i = data_length + 1; 
     } 
    } 
} 

/* Debug point */ 
NSLog(@"pointer: %lu length: %lu",(unsigned long)end_pointer, (unsigned long)data_length); 
NSLog(@"[2] DATA BYTES: %@ with Error: %@",data,error); 

在第二部分中所述的NSData的長度也變爲0

下面是NSLog的輸出,我已經縮短十六進制輸出爲了不要太長。

2015-09-10 21:11:24.935 PicRecover[51550:13961579] [1] Data length: 66528 
2015-09-10 21:11:24.939 PicRecover[51550:13961579] [1] Data: <504b0304 ... 
... 01000000> with Error: (null) 
2015-09-10 21:11:24.960 PicRecover[51550:13961579] pointer: 0 length: 0 
2015-09-10 21:11:24.960 PicRecover[51550:13961579] [2] DATA BYTES: (null) with Error: (null) 

我希望有人比我更瞭解NSData,並能指出我的錯誤。如果您需要更多信息,我可以隨時添加。

非常感謝您提前。

+0

如果分配了* NULL,它將只會'變爲空'*。因此分配了NULL。找出原因並修復使用/假設。 – user2864740

+0

就像你可以從我的代碼中看到的一樣,我沒有指定null。你有什麼想法如何和爲什麼被分配? – jniegsch

+0

再次,**因此NULL *被分配***(或者你或者正在堆棧,這不太可能,或者結果被誤解)。那麼,*哪裏*做的任務發生和*當*他們可以返回NULL?有沒有一種情況是它從未被賦值? – user2864740

回答

1

NSMakeRange發生偏移和長度,你逝去的兩個偏移......這意味着你的範圍比你想象的大了很多,你正在寫遍記憶,給你的目標緩衝區長只是一個字節。

此外,由於使用description方法的結果(調用stringWithFormat:時調用此方法)的結果,您對特定字節值的檢查過於複雜且不可靠。你只可以直接比較的字節值,與任何其他整數類型,例如:

if (byte[0] == 0xFF) ... 

最後仰望break聲明做什麼。

HTH

+0

CRD你的事情範圍可能導致NSData變爲空?我真的很困惑對我來說這是沒有意義的:/我不明白爲什麼上面的幾行我得到所有的數據和我現在得到的幾行。我讀過NSData的Apple API,但我似乎無法找到它爲什麼只是指定null與我指定的原因。我的mac有很多內存和內存,所以我不明白爲什麼它應該釋放數據或用null覆蓋它。 – jniegsch

+0

你試過修復範圍問題嗎?一旦你的範圍大於一個字節,你將覆蓋你的堆棧的一部分,隨着它的增長你覆蓋更多。你所有的局部變量都存儲在堆棧中,而你的輸出不會顯示你的NSData對象變爲null,而是你的本地變量,它以某種方式引用它,你不期望的值。 – CRD

+0

非常感謝您的幫助。我誤解了API,認爲範圍中的第二個變量是結束位置,而它是一個長度。所以範圍導致了這個問題。非常感謝您的幫助! :) – jniegsch

0

要添加到@ CRD的答案,你應該看看memmem &現有的其他功能。

另外:您可以使用CFDataGetBytePtrNSMutableData -mutableBytes直接訪問內部緩衝區,而不是將NSData內容複製到外部緩衝區。

對於NSMakeRange問題 - C允許您覆蓋任意內存。您只爲byte變量分配了一個字節,但是您正在爲該內存位置寫入i + 1個字節。

這意味着您正在寫入內存中正好在byte旁邊的任何信息。

這絕對可以包含您的data指針的內容。

+0

但是,通過將位置(第一個變量在getBytes的範圍內)設置爲'i',將第二個設置爲'i + 1',範圍仍然應該爲1,因此它不應該寫滿整個內存,或者我誤解了for循環和getBytes函數是如何一起工作的? – jniegsch

相關問題