阅读此代码。我在5分钟内在我的办公桌上写了它,这不是生产代码,只是为了展示。然后在底部阅读我的问题:
@interface SomeClass : NSObject {
NSString *currentFruit;
NSMutableArray *fruits;
}
@property (retain) NSString *currentFruit;
@property (retain) NSMutableArray *fruits;
@end
@implementation SomeClass
@synthesize currentFruit, fruits;
-(void) createArray {
self.fruits = [[NSMutableArray alloc] initWithObjects:@"apples",@"oranges",@"grapes",nil];
self.currentFruit = [fruits objectAtIndex:0];
}
-(void)writeToDisk {
NSString *filePath = @"/somePath/file.ext";
NSMutableData *fileData = [NSMutableData data];
NSKeyedArchiver *coder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:fileData];
[coder encodeObject:self.fruits forKey:@"fruitArray"];
[coder encodeObject:self.currentFruit forKey:@"theFruit"];
[coder finishEncoding];
[fileData writeToFile:filePath atomically:YES];
[coder release];
}
-(void)loadDataFromDisk {
NSString *filePath = @"/somePath/file.ext";
NSData *fileData = [[NSData alloc] initWithContentsOfFile:filePah];
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:fileData];
NSMutableArray *decodedFruits = [decoder decodeObjectForKey:@"fruitArray"];
NSString *decodedFruit = [decoder decodeObjectForKey:@"theFruit"];
self.currentFruit = decodedFruit;
self.fruits = decodedFruits;
[decoder release];
[fileData release];
}
假设我使用方法 - (void)createArray来创建我的数组,然后将currentFruit的实例设置为数组中的第一个对象。然后我使用 - (void)writeDataToDisk并将对象存储到文件中。当我使用loadDataFromDisk时,我的应用程序是否仍然知道currentFruit应该是我的fruits数组开头的对象?或者我现在会有两个单独的实例?
我想弄明白这一点。我应该跟踪数组索引而不是跟踪实际对象吗?我想始终引用数组中的对象。这有意义吗?
答案 0 :(得分:2)
尝试使用NSCoding协议使接口混乱。
实现encodeWithCoder和initWithEncoder。 然后,您可以将对象序列化和反序列化为文件或流。
然后你做了以下声明:
NSData *data = [NSKeyedarchiver archivedDataWithRootObject:someClassInstance];
或
SomeClass *instance = [NSKeyedUnarchiver unarchiveObjectWithData:data];
这不能回答你的问题。但是会使你的代码变得更好。
现在你的问题: 您的申请“不知道”当前的水果。由于loadDataFromDisk位于实例的范围内,因此将覆盖实例变量。换句话说:你有一个实例,你将调用一个方法。它的内容将会改变,不会有第二个实例。 如果需要两个实例,请使用NSCoding协议
当您希望将currentfruit分享到更多实例时,请将currentfruit变量设为静态。
答案 1 :(得分:1)
编辑:我撤回了以下答案,不知何故没有意识到你没有使用NSCoder。以下内容适用于通过实现NSCoding并仅提供单个根对象进行编码。如果您希望在您的情况下工作,它将是文档之外的实现细节,因此不能依赖。
我倾向于相信你会得到同样的对象;当您写出同一对象的多个实例并使用返回原始实例的链接时,存档器会检测到。否则他们将无法编写包含循环引用的任何对象层次结构 - 它们只是永久写入磁盘。因此,对象'theFruit'来自数组'fruitArray'的信息在存档中编码。请参阅'Root Object' within the Archives and Serialization Programming Guide。
鉴于您保留了相同的NSKeyedUnarchiver实例,假设下面的代码足够智能以返回相同的对象并不是不合理的。但是,我正在阅读Apple关于存储对象图的重点,并且无法找到对此的明确认可。