2011-09-28 38 views
1

在Objective-C,我想獲得一個包含約14財產使用下面的代碼某個對象的屬性:錯誤而獲取屬性類型大類在Objective-C

-(NSDictionary*) getPropertiesOfClass:(Class) clazz 
{ 
    NSMutableDictionary* dict = [NSMutableDictionary dictionary]; 
    unsigned int outCount, i; 
    objc_property_t *properties = class_copyPropertyList(clazz, &outCount); 
    for(i = 0; i < outCount; i++) 
    { 
     objc_property_t _property = properties[i]; 
     const char *propName = property_getName(_property); 
     if(propName) 
     { 
      const char *propType = getPropertyType(_property); 
      NSString *propertyName = [NSString stringWithCString:propName encoding:NSUTF8StringEncoding]; 
      NSString *propertyType = [NSString stringWithCString:propType encoding:NSUTF8StringEncoding]; 
      [dict setValue:propertyType forKey:propertyName]; 
     } 
    } 
    free(properties); 
    return dict; 
} 

static const char *getPropertyType(objc_property_t property) 
{ 
    const char *attributes = property_getAttributes(property); 
    char buffer[1 + strlen(attributes)]; 
    strcpy(buffer, attributes); 
    char *state = buffer, *attribute; 
    while ((attribute = strsep(&state, ",")) != NULL) 
    { 
     if (attribute[0] == 'T') 
     { 
      return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes]; 
     } 
    } 
    return "@"; 
} 

但我得到了一個但是,當我嘗試使用相同的代碼來獲取小對象(具有3或4個屬性的對象)的屬性列表時,代碼無任何例外地工作,並得到準確的結果。

那麼,如何處理這個錯誤! 謝謝。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSConcreteData initWithBytes:length:copy:freeWhenDone:bytesAreVM:]: absurd length: 4294967294, maximum size: 2147483648 bytes' 
*** Call stack at first throw: 
(
    0 CoreFoundation      0x0101e5a9 __exceptionPreprocess + 185 
    1 libobjc.A.dylib      0x01172313 objc_exception_throw + 44 
    2 CoreFoundation      0x00fd6ef8 +[NSException raise:format:arguments:] + 136 
    3 CoreFoundation      0x00fd6e6a +[NSException raise:format:] + 58 
    4 Foundation       0x00800b6b -[NSConcreteData initWithBytes:length:copy:freeWhenDone:bytesAreVM:] + 135 
    5 Foundation       0x00811801 -[NSData(NSData) initWithBytes:length:] + 72 
    6 solit        0x00033449 -[ObjectMapper(private) getPropertiesOfClass:] + 489 
    7 solit        0x00031fa5 -[ObjectMapper objectFromDictionary:object:] + 197 
    8 solit        0x000327b3 -[ObjectMapper objectFromDictionary:object:] + 2259 
    9 solit        0x00033913 -[NSDictionary(ObjectMapper) toObject:withTypes:] + 243 
    10 solit        0x00031474 -[JsonWSCaller call:types:error:] + 196 
    11 solit        0x0003f4c2 +[SummaryWSCaller getFastData:] + 354 
    12 solit        0x00006fd9 -[PartSearchResultView tableView:didSelectRowAtIndexPath:] + 233 
    13 UIKit        0x00110b68 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140 
    14 UIKit        0x00106b05 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 219 
    15 Foundation       0x0082079e __NSFireDelayedPerform + 441 
    16 CoreFoundation      0x00fff8c3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19 
    17 CoreFoundation      0x01000e74 __CFRunLoopDoTimer + 1220 
    18 CoreFoundation      0x00f5d2c9 __CFRunLoopRun + 1817 
    19 CoreFoundation      0x00f5c840 CFRunLoopRunSpecific + 208 
    20 CoreFoundation      0x00f5c761 CFRunLoopRunInMode + 97 
    21 GraphicsServices     0x012561c4 GSEventRunModal + 217 
    22 GraphicsServices     0x01256289 GSEventRun + 115 
    23 UIKit        0x000a7c93 UIApplicationMain + 1160 
    24 solit        0x00002289 main + 121 
    25 solit        0x00002205 start + 53 
) 
+0

你可以發佈工作碼?你用過ARC嗎? – zekel

+0

在這裏找到它https://github.com/MuhammadHewedy/ObjectMapper/blob/master/ObjectMapper/ObjectMapper/ObjectMapper.m –

回答

4

這與該類的大小和屬性的數量無關。

這可能是因爲你的記憶管理有問題。當沒有太多屬性時,用於檢索const char*變量中的屬性名稱和類型的內存仍然存在,但是當您開始有太多屬性循環時,這些內存區域會被新值刪除,因此崩潰。

這可能與strsep不可重入的事實有關,因此多次循環和使用它每次都使用相同的內部char緩衝區。

你應該讓你的getPropertyType方法直接返回NSData的對象,而不是const char*字節,並使用NSStringinitWithData:encoding:方法來構建從它的字符串(或本initWithData:encoding:呼叫直接轉移到getPropertyType,使這個返回NSString對象直接,這樣你就可以避免管理內存指針區域將被自動釋放不久。


您的問題可能是,你忘了檢查attribute BUF的有效性在嘗試訪問這個緩衝區中的字節之前,特別是它的長度!

特別是您正在使用[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4]未檢查attribute是否至少有4個字符長!

這就是爲什麼在調用dataWithBytes:length:(即內部調用initWithBytes:length:copy:freeWhenDone:bytesAreVM:)崩潰了NSInvalidArgumentException,告訴你通過它的4294967294荒謬的長度(這是-2如果解釋爲有符號整數)

+0

回答編輯,以增加關於例外的真實原因的細節 – AliSoftware

+0

+1000,兄弟,你救了我的命, 謝謝 :) –

相關問題