0

在为 iPhone 学习了 4 周的 Objective-C 之后,我的第一个有用的应用程序几乎完成了。但是,每当当前视图更改时,我仍然需要保存几个实例变量,并在重新打开视图时重新加载它们。

我可以毫无困难地加载具有基本 C 类型(如intBOOL )的变量,但在使用由 Objective-C 对象组成的链表时遇到了困难。

链表由三个指针访问的内存组成:startPointercurrPointerendPointer。每个元素由一个last指针、一个next指针、一个指向嵌套链表 ( nestedPtr ) 的指针和一些变量组成。

我的第一次尝试是在加载代码中执行以下操作:

//dataStorageObj will contain the values to be loaded
dataStorageObj = [[DataSaver alloc] init];
NSData *data =[[NSMutableData alloc] initWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:@"Archive"]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
dataStorageObj = [unarchiver decodeObjectForKey:@"KeyForViewA"];
[unarchiver finishDecoding];
//****************************
//Simple variables loaded here
//****************************
//DataSaver is a class with methods to retrieve its instance variables
//The methods are named after the values they retrieve
startPointer = [dataStorageObj startPointer];
currPointer = [dataStorageObj currPointer];
endPointer = [dataStorageObj endPointer];
[unarchiver release];
[data release];

我在最后放置了一个调试点,所有变量都有正确的值。实际上访问代码中的值(在控制台中这样做)会导致EXC_BAD_ACCESS消息。


接下来,我将链表加载行更改为以下内容:

startPointer = [[PointerClass alloc] initPointerFromList:[dataStorageObj startPointer]];
currPointer = [[PointerClass alloc] initPointerFromList:[dataStorageObj currPointer]];
endPointer = [[PointerClass alloc] initPointerFromList:[dataStorageObj endPointer]];

initPointerFromList方法

-(PointerClass *)initPointerFromList:(PointerClass *)theList
{
    last = theList.last;
    nestedPointer = [[NestedPointerClass alloc] initNestedPointerFromList:theList.nestedPointer];
    //****************************************
    //Other variables loaded from theList here
    //****************************************
    if (theList.next != nil)
    {
        next = [[PointerClass alloc] initPointerFromList:theList.next];
    }

    return self;
}

现在的问题是指针都指向单独的链表,所以我编写了方法来检索 currPointer 引用的链表的开始和结束位置:

currPointer = [[PointerClass alloc] initPointerFromList:[dataStorageObj currPointer]];
endPointer = [currPointer lastElement];
startPointer = [currPointer firstElement];

我的问题有三个:

  1. 是否需要使用initPointerFromList等方法为已加载的链表分配内存?
  2. 有没有比使用lastElementfirstElement方法搜索列表更有效的方法来维护currPointerendPointerstartPointer之间的关系?
  3. 我提供的加载代码背后的技术有问题吗?没有它,我没有问题;有了它,我仍然收到BAD_ACCESS消息。我想知道这些消息是否与加载代码有关,或者是否与我在整个应用程序的其余部分中处理对象分配的方式有关。

提前致谢!

4

2 回答 2

2

正如您所发现的,指针往往是档案的痛点。您是否可以使用 NSMutableArray 来满足您的存储需求,因为这可能会为您简化问题。

http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/Archiving/Archiving.html#//apple_ref/doc/uid/10000047

如果您不打算使用 NSMutableArray,您可能希望创建一个响应 encodeWithCoder 消息的容器类,并以这种方式对列表进行编码。您不会存储指针,而是使用它们来遍历您的容器,并以某种确定的顺序对其进行归档。

于 2009-03-20T15:39:10.190 回答
1

您想通过使用链表获得什么?

你正试图将另一种语言的东西硬塞到 Objective-C 中,结果是你想做的很多工作。

要么使用 NSArray/NSMutableArray,要么使用 NSDictionary/NSMutableDictionary,其中包含您尝试存储的特定元素的键。

于 2009-03-20T22:52:19.867 回答