我正在为iOS开发todo list app。我有一个名为ToDoItem的自定义类。我的设计是将用户内容写入文本文件,并在用户再次打开应用程序时从文件中读回。我已经为我的ToDoItem类实现了确认NSCoding协议的方法。
下面给出了写入数据的方法
- (void)loadData{
if ([[NSFileManager defaultManager] fileExistsAtPath:_appFile]) {
NSFileHandle *handle = [NSFileHandle fileHandleForReadingAtPath:_appFile];
if (handle) {
NSData *data = [handle readDataToEndOfFile];
if (data) {
ToDoItem *item;
NSMutableArray *arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
for (item in arr) {
[_toDoItems addObject:item];
}
}
[handle closeFile];
}
}}
下面给出了读取数据的方法
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_itemName forKey:ITEMNAME];
[aCoder encodeObject:_date forKey:DATE];
[aCoder encodeBool:_isDone forKey:DONE];
[aCoder encodeInteger:_row forKey:ROW];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
_itemName = [aDecoder decodeObjectForKey:ITEMNAME];
_date = [aDecoder decodeObjectForKey:DATE];
_isDone = [aDecoder decodeBoolForKey:DONE];
_row = [aDecoder decodeIntegerForKey:ROW];
}
return self;
}
现在我只能将单个ToDoItem写入文件并能够读取它。如果我写了多个ToDoItem的对象,在阅读它的时候我会得到" [NSKeyedUnarchiver initForReadingWithData:]:难以理解的存档"例外。 我担心的是,当用户重新启动应用程序时,我只想在用户保存数据并再次检索所有信息时附加我的ToDoItem对象。
NSCoding方法
test.sh
提前致谢
答案 0 :(得分:1)
添加新项目时,无法将新数据附加到文件末尾 - 您需要每次都完全替换该文件。
您需要将新项目添加到现有项目数组中,然后保存完整数组的存档。如果您的新待办事项视图控制器只返回新项目或nil并在“外部”VC中完成保存,则可能更清晰
<ImageView
android:id="@+id/icon"
android:layout_width="@dimen/slidingtab_item_icon_size"
android:layout_height="@dimen/slidingtab_item_icon_size"
android:layout_centerInParent="true"
android:src="@drawable/ic_event_black_18dp"/>
答案 1 :(得分:1)
我建议使用属性列表文件而不是文本文件。 这是一个在plist文件中加载和保存todoItems的解决方案。
<强>假设:强>
_appFile
:一个NSString变量,包含plist文件的路径
__toDoItems
:一个初始化的NSMutableArray变量来保存待办事项
两种方法都使用NSPropertyListSerialization
,它提供了更多的读写选项
- (void)loadData
{
NSDictionary *prefs = nil;
NSData *plistData = [NSData dataWithContentsOfFile:_appFile];
if (plistData) {
prefs = (NSDictionary *)[NSPropertyListSerialization
propertyListWithData:plistData
options:NSPropertyListImmutable
format:NULL
error:nil];
}
if (prefs) {
NSArray *itemDataArray = prefs[@"todoItems"];
if (itemDataArray) {
[_toDoItems removeAllObjects]; // might be not needed
for (itemData in itemDataArray) {
[_toDoItems addObject:(ToDoItem *)[NSKeyedUnarchiver unarchiveObjectWithData:itemData]];
}
}
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// if cancel button is pressed
if (sender != self.saveBtn) {
return;
}
// if save button is pressed
else {
NSMutableArray *itemDataArray = [[NSMutableArray alloc] init];
for (ToDoItem *item in _toDoItems) {
[itemDataArray addObject:[NSKeyedArchiver archivedDataWithRootObject:item]];
}
NSError *error = nil;
NSDictionary *prefs = @{@"todoItems" : itemDataArray};
NSData *plistData = [NSPropertyListSerialization dataWithPropertyList: prefs
format:NSPropertyListBinaryFormat_v1_0
options:0
error:&error];
if (plistData) {
[plistData writeToFile:_appFile atomically:YES];
}
else {
// do error handling
}
}