gpt4 book ai didi

ios - Objective-C 中的访问者模式

转载 作者:技术小花猫 更新时间:2023-10-29 10:35:03 25 4
gpt4 key购买 nike

我一直在寻找在 Objective-C 中实现访问者设计模式的最佳方式。由于该语言不支持方法重载,因此在 Java 中可能会发现的“传统”实现似乎是不可能的。

在我当前的实现中,我有一个 Visitor 协议(protocol)、一个 Visitor 类和该 Visitor 类的几个子类,以及要访问的各种对象。一旦被访问的对象接受了访问者,它们就会调用访问者的访问方法,将自己作为参数传递。 visit 方法接受一个 id,然后对其进行类型转换并调用

[self performTasksOnObjectClass: (ObjectClass *)object];

作为 if/elseif/else block 的一部分。这些调用由相关的 Visitor 子类接收,并且 Visitor 在对象上执行它需要的任何任务。

有没有比这更好的实现访问者模式的方法?我不喜欢在 if/elseif/else block 中诉诸“isKindOfClass”或“isMemberOfClass”调用。它只是看起来笨重和不优雅。此外,以这种方式实现 Visitor 方法仍然“值得”吗?被访问的对象仍然可以对访问者一无所知,但还有其他方法可以实现这一点。

已经有人建议委托(delegate)或类集群可能是访问者模式的更合适的替代方案。我很想知道你们的想法!

编辑:我实际上在子类中调用了不同命名的方法,我已经把它弄清楚了。

最佳答案

您可以使用一些内省(introspection)/反射(reflection)来使它更清晰一些。您不能重载方法名称,但可以避免编写这样的 switch 语句:

- (void)performTasks:(id)object
{
Class class = [object class];
while (class && class != [NSObject class])
{
NSString *methodName = [NSString stringWithFormat:@"perform%@Tasks:", class];
SEL selector = NSSelectorFromString(methodName);
if ([self respondsToSelector:selector])
{
[self performSelector:selector withObject:object];
return;
}
class = [class superclass];
}
[NSException raise:@"Visitor %@ doesn't have a performTasks method for %@", [self class], [object class]];
}

您的实际 performTasks 方法将按如下方式命名:

- (void)performFooTasks:(Foo *)foo
{
//tasks for objects of class Foo
}

- (void)performBarTasks:(Bar *)bar
{
//tasks for objects of class Bar
}

etc...

注意:如果您使用的是 ARC,您将通过以这种方式从字符串创建选择器来获得虚假警告,因为它无法在编译时告知应该为方法参数。您可以使用 #pragma 使这些警告静音,如下所示:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self performSelector:selector withObject:object];
#pragma clang diagnostic pop

关于ios - Objective-C 中的访问者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9366079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com