您需要创建一个递归释放结构的函数,例如:
void free_nodes(struct node *n)
{
if (n != NULL)
{
free_nodes(n->nextLink);
free_nodes(n->variationLink);
[n->comment release];
[n->move release];
free(n);
}
}
然后从您的dealloc
方法中调用它:
- (void)dealloc
{
free_nodes(_root_node);
[super dealloc];
}
其他的建议:
- 您需要一个指向变体主线的链接,这相当于
goBack
指针,但用于变体。这将允许您横向回到任何节点的主线,因为目前没有办法完全横向执行您的树。
- 我会重命名为
goBack
,prev
和nextLink
,next
但这真的取决于你。variationLink
variation
- 您需要使用内部格式存储移动,而不是
NSString
. 字符串应该只在显示期间生成(在视图的 draw 方法中)。这允许您实际使用移动数据,而不必再次解析字符串(非常昂贵),并且仅在显示期间进行字符串转换允许您根据用户偏好更改移动字符串的生成方式(短代数符号,长代数符号,坐标符号,使用块字符字体而不是字母等)。
来自 OP 的问题后编辑:为了让您的树存储多个变体,您需要创建变体的双向链接列表。因此该节点将成为两个双向链表的一部分。用 C++ 编写会有所帮助,但如果您使用的是 C,我会用 C 来展示它:
typedef struct node
{
Move move; // Holds the move (this can be done using a 32-bit unsigned integer).
struct node *prev;
struct node *next;
struct node *variation;
struct node *mainline;
NSString *comment;
} Node;
这里的mainline
链接指向之前的变化,NULL
如果这是主线移动的话。
移动 1.e4 e5 (1...Nf6 a4) (1...Nc6 b4) 2.Nc3 将使用这样的树进行保存(如果链接未显示在节点上,则它们是NULL
):

我在我正在开发的国际象棋程序中使用这种方法,它运行得很好。重新迭代;我将数据(此节点)与演示文稿(包含 UI 中显示的移动文本的字符串)分开。生成的移动字符串应该以完全不同的方式保存;也许是 Core Text,但我使用的是自定义方法。