通过具有过早停止条件的块遍历树
Tree Traversal via Blocks with a premature stopping condition
我正在对二叉树进行中序遍历,并在每个节点上执行特定的方法。我使用如下所示的 inOrderTraversalWithOperation:
方法执行此操作,该方法使用块来定义每个节点所需的功能。
-(void) inOrderTraversalWithOperation:(void (^) (BinaryTreeNode *))operation
{
[self.leftChild inOrderTraversalWithOperation:operation];
if (operation)
{
operation(self);
}
[self.rightChild inOrderTraversalWithOperation:operation];
}
假设我想在 Block 执行遇到特定条件时停止。一种方法是将 inOrderTraversalWithOperation:
return 设为 BOOL
,并将块 return 设为 BOOL
,如下所示。
但我想知道我是否可以使用 Apple 在其许多 API 中使用的 BOOL *stop
方法来做到这一点。带有该标志的块如何工作 "underneath"?
-(BOOL) inOrderTraversalWithStopOperation:(BOOL (^) (BinaryTreeNode *))operation
{
BOOL shouldStop = NO;
shouldStop = [self.leftChild inOrderTraversalWithStopOperation:operation];
if (operation !=nil && shouldStop == NO)
{
shouldStop = operation(self);
}
if (!shouldStop)
{
shouldStop = [self.rightChild inOrderTraversalWithStopOperation:operation];
}
return shouldStop;
}
编辑
根据 Josh 的评论,看起来 BOOL *stop
会允许这样做,但我仍然需要 inOrderTraversalWithStopOperation:
到 return 一个 BOOL
-(BOOL) inOrderTraversalWithStopOperation:(void (^) (BinaryTreeNode *, BOOL *))operation
{
BOOL shouldStop = NO;
shouldStop = [self.leftChild inOrderTraversalWithStopOperation:operation];
if (operation !=nil && shouldStop == NO)
{
operation(self, &shouldStop);
}
if (!shouldStop)
{
shouldStop = [self.rightChild inOrderTraversalWithStopOperation:operation];
}
return shouldStop;
}
枚举块的 "stop" 参数就像任何其他间接 return 值一样:您从一个范围传递一个 地址 以便下一个范围可以把东西放在那里。然后在原始范围内可以使用某些东西。
要向您的操作类型添加停止标志,您需要更改其签名
typedef void (^NodeOperation)(BinaryTreeNode *, BOOL *);
在 Block 的调用上下文中,您将执行您已经完成的操作:为此标志创建一个 BOOL 并将其设置为 NO
。然后你将它的地址传递给块:operation(self, &stop);
.
在操作中,如有必要,您可以通过取消引用并分配一个值来设置标志:*stop = YES;
(最好先检查它是否不是 NULL
;取消引用 NULL
是非法的)。
回到控制范围,做你已经在做的事情:在每次操作后检查标志并决定做什么。
我对 What is the BOOL *stop argument for enumerateObjectsUsingBlock: used for?
的相关回答中有此机制的代码示例
要控制递归方法调用,您必须以某种方式将信息传回。您可以使用直接 return 值最轻松地做到这一点。另一种选择(虽然我认为在这种情况下它不会给你带来任何好处)是向方法添加一个 BOOL
指针参数;然后你可以继续将相同的引用传递给每个级别。 (这可能意味着创建一个辅助方法,以便原始调用者不必担心该参数。)
我正在对二叉树进行中序遍历,并在每个节点上执行特定的方法。我使用如下所示的 inOrderTraversalWithOperation:
方法执行此操作,该方法使用块来定义每个节点所需的功能。
-(void) inOrderTraversalWithOperation:(void (^) (BinaryTreeNode *))operation
{
[self.leftChild inOrderTraversalWithOperation:operation];
if (operation)
{
operation(self);
}
[self.rightChild inOrderTraversalWithOperation:operation];
}
假设我想在 Block 执行遇到特定条件时停止。一种方法是将 inOrderTraversalWithOperation:
return 设为 BOOL
,并将块 return 设为 BOOL
,如下所示。
但我想知道我是否可以使用 Apple 在其许多 API 中使用的 BOOL *stop
方法来做到这一点。带有该标志的块如何工作 "underneath"?
-(BOOL) inOrderTraversalWithStopOperation:(BOOL (^) (BinaryTreeNode *))operation
{
BOOL shouldStop = NO;
shouldStop = [self.leftChild inOrderTraversalWithStopOperation:operation];
if (operation !=nil && shouldStop == NO)
{
shouldStop = operation(self);
}
if (!shouldStop)
{
shouldStop = [self.rightChild inOrderTraversalWithStopOperation:operation];
}
return shouldStop;
}
编辑
根据 Josh 的评论,看起来 BOOL *stop
会允许这样做,但我仍然需要 inOrderTraversalWithStopOperation:
到 return 一个 BOOL
-(BOOL) inOrderTraversalWithStopOperation:(void (^) (BinaryTreeNode *, BOOL *))operation
{
BOOL shouldStop = NO;
shouldStop = [self.leftChild inOrderTraversalWithStopOperation:operation];
if (operation !=nil && shouldStop == NO)
{
operation(self, &shouldStop);
}
if (!shouldStop)
{
shouldStop = [self.rightChild inOrderTraversalWithStopOperation:operation];
}
return shouldStop;
}
枚举块的 "stop" 参数就像任何其他间接 return 值一样:您从一个范围传递一个 地址 以便下一个范围可以把东西放在那里。然后在原始范围内可以使用某些东西。
要向您的操作类型添加停止标志,您需要更改其签名
typedef void (^NodeOperation)(BinaryTreeNode *, BOOL *);
在 Block 的调用上下文中,您将执行您已经完成的操作:为此标志创建一个 BOOL 并将其设置为 NO
。然后你将它的地址传递给块:operation(self, &stop);
.
在操作中,如有必要,您可以通过取消引用并分配一个值来设置标志:*stop = YES;
(最好先检查它是否不是 NULL
;取消引用 NULL
是非法的)。
回到控制范围,做你已经在做的事情:在每次操作后检查标志并决定做什么。
我对 What is the BOOL *stop argument for enumerateObjectsUsingBlock: used for?
的相关回答中有此机制的代码示例要控制递归方法调用,您必须以某种方式将信息传回。您可以使用直接 return 值最轻松地做到这一点。另一种选择(虽然我认为在这种情况下它不会给你带来任何好处)是向方法添加一个 BOOL
指针参数;然后你可以继续将相同的引用传递给每个级别。 (这可能意味着创建一个辅助方法,以便原始调用者不必担心该参数。)