2011-07-14 124 views
11

在我的iPhone應用程序中,我有一個名爲Contact的類,它由ABRecordRef組成,用作對特定聯繫人的引用。將數據存儲到NSUserDefaults

我需要將這些聯繫人的組存儲在NSUserDefaults中,但由於Contact是一個自定義類,所以事情並不奏效。

任何想法在這種情況下做什麼?

回答

29

您不能將NSUserDefaults用於自定義類。從文檔:

NSUserDefaults類提供用於訪問 常見類型如浮標方便的方法,雙打,整數,布爾值,和URL。甲 缺省對象必須是一個屬性列表,也就是,的一個實例(用於集合或 的實例的組合):NSDataNSStringNSNumberNSDateNSArray,或者NSDictionary。如果要存儲任何其他類型的對象,則通常應將其歸檔,以創建NSData的實例 。

嘗試使用NSData。例如,自定義對象加載到一個數組,你可以做

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults]; 
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"]; 
if (dataRepresentingSavedArray != nil) 
{ 
     NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray]; 
     if (oldSavedArray != nil) 
       objectArray = [[NSMutableArray alloc] initWithArray:oldSavedArray]; 
     else 
       objectArray = [[NSMutableArray alloc] init]; 
} 

要存檔的數據,使用:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:objectArray] forKey:@"savedArray"]; 

這將所有的工作,只要你自定義對象與NSCoding協議規定:

- (void)encodeWithCoder:(NSCoder *)coder; 
{ 
    [coder encodeObject:label forKey:@"label"]; 
    [coder encodeInteger:numberID forKey:@"numberID"]; 
} 

- (id)initWithCoder:(NSCoder *)coder; 
{ 
    self = [[CustomObject alloc] init]; 
    if (self != nil) 
    { 
     label = [coder decodeObjectForKey:@"label"]; 
     numberID = [coder decodeIntegerForKey:@"numberID"]; 
    } 
    return self; 
} 

ABRecord是不透明C型,所以它不是在Objective-C的讀出的對象。這意味着您無法擴展它,您無法在其上添加類別,也無法向其發送消息。您可以做的唯一事情就是撥打ABRecord中所述的呼叫功能,並以ABRecord作爲參數。

你可以做兩件事情能夠保持在ABRecord周圍引用的信息:

  1. ABRecordGetRecordID()ABRecord小號idABRecordID被定義爲int32_t,因此您可以將其轉換爲NSInteger並將其存儲在任何地方。您可以稍後從ABAddressBookGetPersonWithRecordID()ABAddressBookGetGroupWithRecordID()獲取記錄。但是,記錄可能會被用戶或其他應用程序更改或甚至刪除。

  2. 將記錄內的所有值複製到標準NSObject子類中,並使用NSCoding來存儲它。當然,您將不會從用戶可能做出的記錄更改或添加中受益。

+0

但我不能編碼ABRecordRef,因爲它不是一個對象。 – CodeGuy

+0

對,我做到了。但我如何編碼ABRecordRef – CodeGuy

+0

@ reising1:請參閱上文。 – PengOne

1

ABRecordRef似乎是一個const void *,所以其存儲在NSUserDefaults,你必須把它包在NSDataNSData *d = [[NSData alloc] initWithBytes:thePointer length:sizeof(ABRecordRef)];

+0

是的,但我如何存儲ABRecordRef,因爲它不是一個明顯的對象 – CodeGuy

+0

你知道它至少是什麼?對象,結構,基類型? – 2011-07-14 16:58:38

2

那麼,Apple's recommendation是存儲記錄標識符,名字和姓氏。然後,您可以嘗試通過標識符從地址簿中檢索聯繫人,如果未找到該記錄或者如果該記錄不是合適的人,請嘗試按姓氏和名字進行檢索(因爲記錄標識符可能會根據您的來源地址簿數據)。

這可能是也可能不是你想要的,這取決於你存儲數據的原因。但是,你可以很容易地將這三個值放入NSDictionary中,並將字典寫入NSUserDefaults

0

實際上,您可以使用轉換爲vCard表示形式(即CFStringRef)將其存儲,該表示形式可以輕鬆用作NSString。

相關問題