我有一個名爲XYZ的類繼承NSObject和一個包含XYZ對象的數組。我需要將此數組寫入文檔目錄中的plist文件。在嘗試[array writeToFile ....]之後,我發現writeToFile失敗,因爲該數組包含XYZ類的自定義對象。將數組保存到Plist文件,其中包含自定義對象iPhone
可能的解決方案是將對象轉換爲NSData。有什麼不同的方式來實現這個?我發現NSCoding是合適的,但不知道如何使用它。任何幫助將不勝感激。
我有一個名爲XYZ的類繼承NSObject和一個包含XYZ對象的數組。我需要將此數組寫入文檔目錄中的plist文件。在嘗試[array writeToFile ....]之後,我發現writeToFile失敗,因爲該數組包含XYZ類的自定義對象。將數組保存到Plist文件,其中包含自定義對象iPhone
可能的解決方案是將對象轉換爲NSData。有什麼不同的方式來實現這個?我發現NSCoding是合適的,但不知道如何使用它。任何幫助將不勝感激。
關於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。
您需要實施兩種方法:-initWithCoder:
和-encodeWithCoder:
。閱讀NSCoding
文檔;他們非常簡單直接的方法。您基本上想要用與其名稱相對應的鍵對您的實例變量進行編碼/解碼。
這很簡單。對於給定的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
實施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];
要刪除特定對象,請執行以下操作? – raaz
符合您的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
非常感謝..:) – Shri
我在 - (id)initWithCoder:(NSCoder *)解碼器在每一行中發生內存泄漏。你知道可能的原因是什麼? (我的iVar1和ivar2是字符串) – Shri
你在dealloc方法中發佈了它們嗎? –