2011-11-13 91 views
2

我有一個名爲XYZ的類繼承NSObject和一個包含XYZ對象的數組。我需要將此數組寫入文檔目錄中的plist文件。在嘗試[array writeToFile ....]之後,我發現writeToFile失敗,因爲該數組包含XYZ類的自定義對象。將數組保存到Plist文件,其中包含自定義對象iPhone

可能的解決方案是將對象轉換爲NSData。有什麼不同的方式來實現這個?我發現NSCoding是合適的,但不知道如何使用它。任何幫助將不勝感激。

回答

9

關於Ray Wenderlich's blog有一個非常好的教程,它解釋瞭如何使用NSCoding。

簡單,你只需要執行* - (空)encodeWithCoder:(NSCoder )編碼和* - (ID)的initWithCoder:(NSCoder )解碼器方法,你的對象,尊重NSCoding協議這樣的:

// Header 
@interface AnObject: NSObject <NSCoding> 

// Implementation 
- (void) encodeWithCoder:(NSCoder *)encoder { 
    [encoder encodeObject:ivar1 forKey:@"ivar1"]; 
    [encoder encodeFloat:ivar2 forKey:@"ivar2"]; 
} 

- (id)initWithCoder:(NSCoder *)decoder { 
    self = [super initWithCoder:coder]; 
    ivar1 = [[coder decodeObjectForKey:@"ivar1"] retain]; 
    ivar2 = [[coder decodeObjectForKey:@"ivar2"] retain]; 
    return self; 
} 

您還可以查看官方文檔here

+0

非常感謝..:) – Shri

+0

我在 - (id)initWithCoder:(NSCoder *)解碼器在每一行中發生內存泄漏。你知道可能的原因是什麼? (我的iVar1和ivar2是字符串) – Shri

+0

你在dealloc方法中發佈了它們嗎? –

0

您需要實施兩種方法:-initWithCoder:-encodeWithCoder:。閱讀NSCoding文檔;他們非常簡單直接的方法。您基本上想要用與其名稱相對應的鍵對您的實例變量進行編碼/解碼。

0

這很簡單。對於給定的Foo類:

#import <Foundation/Foundation.h> 

@interface Foo : NSObject <NSCoding> { 
    NSArray* bar_; 
    NSUInteger baz_; 
} 

@property (nonatomic, retain) NSArray *bar; 
@property (nonatomic, assign) NSUInteger baz; 

@end 

所有你需要做的,以符合NSCoding協議是落實initWithCoder:decodeWithCoder消息:

#import "Foo.h" 

@implementation Foo 
@synthesize bar = bar_; 
@synthesize baz = baz_; 

#pragma mark - NSCoding 

- (void)encodeWithCoder:(NSCoder *)encoder { 
    [encoder encodeObject:self.bar forKey:@"bar"]; 
    [encoder encodeInteger:self.baz forKey:@"baz"]; 
} 

- (id)initWithCoder:(NSCoder *)decoder { 
    if ((self = [super init])) { 
     self.bar = [decoder decodeObjectForKey:@"bar"]; 
     self.baz = [decoder decodeIntegerForKey:@"baz"]; 
    } 
    return self; 
} 

- (void) dealloc { 

    [bar_ release]; 
    [super dealloc];  
} 

@end 
9

實施encodeWithCoder:initWithCoder:這裏自定義類是後如何書寫和閱讀:

寫:

NSError *error; 
NSData* archiveData = [NSKeyedArchiver archivedDataWithRootObject:yourClassInstance]; 
[archiveData writeToFile:filePath options:NSDataWritingAtomic error:&error]; 

閱讀:

NSData *archiveData = [NSData dataWithContentsOfFile:filePath]; 
YourClass *yourClassInstance = (NSArray*)[NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; 
+0

要刪除特定對象,請執行以下操作? – raaz

1

符合您的XYZ類的NSCoding協議的確很適合你想要做什麼。要做到這一點,NSCoding協議添加到您的類的接口聲明:

@interface XYZ <NSCoding> 

然後,你需要實現encodeWithCoder:和的initWithCoder:在您的實現。 「編碼器編碼」意思是「把你的對象的當前狀態,並打包成一個通用的對象,稱爲'編碼器'」。 「帶編碼器的初始化」意味着「給定一個已經包裝好的編碼器對象,配置自己的數據打包到編碼器中」。在這兩種方法中,'編碼器'將是NSCoder的實例,其具有用於編碼(「打包」)和解碼(「解包」)基本類型的非常簡單的接口。

這裏是一個示例實現:

@implementation XYZ 
- (id)initWithCoder:(NSCoder*)encoder 
{ 
    self = [self init]; 

    if (self) 
    { 
     self.myIntProperty = [encoder decodeIntForKey:@"myInt"]; 
    } 

    return self; 
} 

– (void)encodeWithCoder:(NSCoder*)decoder 
{ 
    [decoder encodeInt:self.myIntProperty forKey:@"myInt"]; 
} 

@end 
相關問題