2014-10-03 32 views
-1

我有一個自定義對象保存到NSUserDefaults。我不使用核心數據,因爲它是我的一個對象。我正在嘗試創建一個方法,該方法接受此類型的新對象,並將其與此類型的已保存對象中的數據結合使用。嘗試遍歷obj-c對象屬性並將它們複製到另一個對象

這是我到目前爲止,但它是錯誤的,因爲一些對象是不同類型(BOOL,NSNumber,NSString,NSDictionary等)。我越來越

if (request) { 
    unsigned int numberOfProperties = 0; 
    objc_property_t *propertyArray = class_copyPropertyList(
     [AmbulanceRequest class], &numberOfProperties); 

    for (NSUInteger i = 0; i < numberOfProperties; i++) 
    { 
     objc_property_t property = propertyArray[i]; 
     NSString *name = [[NSString alloc] initWithUTF8String:property_getName(property)]; 
     NSString *attributesString = [[NSString alloc] initWithUTF8String: 
      property_getAttributes(property)]; 

     if(nil == [request valueForKey:name]) { <--- error here BOOL cannot be nil 
      [request setValue:[savedRequest valueForKey:name] forKey:name]; 
     } 
    } 
} 

錯誤是:[NSKeyedUnarchiver initForReadingWithData:]: data is NULL

UDPATE:我只是用解碼器和編碼

。當編碼和解碼一般我從來沒有問題。就在上面的代碼中。例如,這裏是一個拋出錯誤的屬性。

當然這些都在適當的encodeWithCoder和initWithCoder方法中。

@property (nonatomic, assign) BOOL * trip; 
self.roundTrip = [decoder decodeBoolForKey:@"trip"]; 
[encoder encodeBool:self.roundTrip forKey:@"trip"]; 

////更新2://////

這裏是我的方法的全部代碼。正如你所看到的,在迭代任何屬性發生之前,對象會被拉回並解碼。我有兩個BooRequests舊的和新的。如果新的屬性沒有這些相同的屬性,我正嘗試將舊屬性的屬性保存到新的屬性中。

+(void) saveRequest:(BooRequest*)request { 

    // If current request then we need to save off the unSetPings 
    BooRequest *savedRequest = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] 
                          objectForKey:kCurrentActiveRequest]]; 
    if(request){ 

     unsigned int numberOfProperties = 0; 
     objc_property_t *propertyArray = class_copyPropertyList([BooRequest class], &numberOfProperties); 

     #warning YO!!! this FOR LOOP is *NOT* done and probably doesn't even work!!! 
     for (NSUInteger i = 0; i < numberOfProperties; i++) 
     { 
      objc_property_t property = propertyArray[i]; 
      NSString *name = [[NSString alloc] initWithUTF8String:property_getName(property)]; 
      NSString *attributesString = [[NSString alloc] initWithUTF8String:property_getAttributes(property)]; 

      if ([[[NSUserDefaults standardUserDefaults] dictionaryRepresentation].allKeys containsObject:@"keyForNonMandatoryObject"]) { 
       id thing = [request valueForKey:name]; 

       if(NULL == [request valueForKey:name] || nil == thing){ 
        [request setValue:[savedRequest valueForKey:name] forKey:name]; 
       } 
      } 

      if(savedRequest) { 
       request.unSentPings = [[NSMutableArray alloc] initWithArray:savedRequest.unSentPings]; 
      } 

      request.nextButtonToShowIndex = savedRequest.nextButtonToShowIndex; 
     } // end for loop 

    } else { 

     STPingSender *sender = [[STPingSender alloc] init]; 
     BooRequest *req = [BooRequest currentRequest]; 
     if(req && req.unSentPings && [req.unSentPings count] > 0){ 
      [sender sendToServer:((BooRequest*)[BooRequest currentRequest]).unSentPings]; 
     } 
    } 


    [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:request] 
                  forKey:kCurrentActiveRequest]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 

這是我的最終目標,我有一個BooRequest,它是從服務器本地保存的。我在本地進行更改。 90%的時間不是從我需要在本地更新的服務器更新。但是,當我需要新的本地數據與新的服務器數據合併。但是我添加的本地數據只能在本地使用,服務器從不使用這些附加數據。它只需要在本地合併。我迭代的原因是,我不希望每次更新此方法時,此Objective-c類都會添加新屬性。我想要一些只是說遍歷屬性的動態代碼,並且當您找到與舊對象和新對象相匹配的屬性時,請將舊對象屬性複製到新對象中。

+0

發佈您在其中存檔對象的代碼。 – 2014-10-03 20:33:09

+0

它只是簡單的解碼器和編碼器。見上面的更新。 – jdog 2014-10-03 20:48:56

+1

我沒有在這裏得到任何東西 - 向我們展示觸發解碼的代碼 - 我的意思是......某些東西必須這樣做,因爲你聲稱在上面的代碼中崩潰 - 如果你還不知道,設置斷點找出何時嘗試解碼 – 2014-10-21 19:17:25

回答

1
id dataObject = [[NSUserDefaults standardUserDefaults] objectForKey:kCurrentActiveRequest]; 
BooRequest *savedRequest = [NSKeyedUnarchiver unarchiveObjectWithData:dataObject]; 

當dataObject時是零,這意味着在用戶默認值沒有這樣的鍵,第二行會發出[NSKeyedUnarchiver initForReadingWithData:]: data is NULL錯誤,在這種情況下,應該不取消存檔,如果新BooRequest對象不是零,您可以直接將新對象保存爲用戶默認值。

id thing = [request valueForKey:name]; 

對於那些原始類型如BOOL或NSInteger的的屬性時,thingNO0分別當你不設置的屬性的值,這意味着if(NULL == [request valueForKey:name] || nil == thing)檢查總是假並且新請求對象不會從舊的更新。我建議你將這些屬性更改爲NSObject類型,以便檢查通過。

@property (nonatomic, strong) NSNumber* boolProperty; 
@property (nonatomic, strong) NSNumber *integerProperty; 

希望有所幫助。

-1

我不確定你爲什麼試圖在NSUserDefaults中存儲自定義對象......通常比它更值得痛苦。

爲什麼不創建一個NSDictionary並將其保存到NSUserDefaults?然後你的BooRequest類可以從字典中初始化,也可以從字典中合併。您也可以在BooRequest中創建方法-saveToUserDefaults,該方法在完成時將其保存回來。根據BooRequest的實際情況,如果您所做的只是存儲一些鍵值對,則可能不需要自定義子類。

這將有助於查看您的本地數據的外觀,以及您的遠程數據的外觀,然後獲得所需的結果。

+0

BooRequest是我的自定義對象。那麼你是說廢棄我的自定義對象,而是使用NSDictionary來代替?如果這樣做可能會有很多工作,因爲我必須手動遍歷服務器結果才能在RestKit自動映射到自定義BooRequest時查找BooRequest。 – jdog 2014-10-23 21:44:31

-1
  • 您不應該盲目地遍歷所有對象屬性,而是選擇那些值得保存的對象。

  • 正如在另一個答案中所說的,不要使用NSUserDefaults這個。如果您不想使用Core Data,我推薦serializing Property Lists。作爲獎勵,您將能夠檢查/手動編輯您的對象值。

相關問題