Objective-C 中的空对象模式

发布于 2024-07-16 21:06:47 字数 606 浏览 7 评论 0原文

在 Java 中,很容易编写以下设计代码:

public abstract class Pizza {
    public static final Pizza.NULL = new Pizza() {
        /* "null" implementations */
    }

    /* actual/abstract implmentations */
}

在 Objective-C 中实现相同高效场景的首选方法是什么? 我一直无法找到有关该主题的任何文档,并且我尝试了使用 static const#define 等几种不同的方案,但似乎都不起作用以及上面的Java方法。

我想避免编写一个具体的 NullPizza 类,它有一个静态方法来获取单例实例,因为它看起来更“合适”,因为它是最高级别接口的某些最终属性/字段。 (在本例中为披萨。)

编辑: 虽然我了解由于 Obj-C 处理对“nil”的方法调用的独特方法而具体如何处理 NULL 模式,但其他静态常见实例又如何呢? ,例如 Response.YES 和 Response.NO? (请参阅评论进行讨论。)

In Java, it is very easy to code the following design:

public abstract class Pizza {
    public static final Pizza.NULL = new Pizza() {
        /* "null" implementations */
    }

    /* actual/abstract implmentations */
}

What is the preferred method to attain the same efficient scenario in Objective-C? I have been unable to find any documentation on the subject, and I have tried a couple different scenarios with static const, #define etc. but none of them seem to work out as well as the Java method above.

I would like to avoid writing a concrete NullPizza class that has a static method to obtain the singleton instance, as it seems more 'proper' for it to be some final property/field of the highest-level interface. (Pizza, in this case.)

Edit: While I understand how the NULL pattern specifically would be handled due to Obj-C's unique method of handling method calls to 'nil', what about other static common instances, such as Response.YES and Response.NO? (See comments for discussion.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

羁〃客ぐ 2024-07-23 21:06:47

Objective-C 中不需要这种类型的模式,因为向类的 nil 实例发送消息不被视为运行时错误。 如果该方法具有已定义的返回类型,则存在从消息传送 nil 对象时定义的返回(例如,在消息传送 nil 对象时返回整数的方法返回 0)。

There is no need for this type of pattern in Objective-C because it is not considered a runtime error to message a nil instance of a class. If the method has a defined return type, there are defined returns from messaging a nil object (e.g., methods that return an integer return 0 when messaging a nil object).

澜川若宁 2024-07-23 21:06:47

有两件事可以提供帮助。 第一个是 nil,Objective-C 相当于 Java NULL 指针 - 它实际上可以接收消息并响应它们。 如果返回值是对象,它将始终返回 nil;如果返回值是某种原始类型,则始终返回 0。 因此,如果对象的 Null 行为是“不执行任何操作”,您可以轻松地使用 nil 作为 Null 值。

另一件有用的事情是当您需要在容器对象中存储占位符或 null 值时 - 如果您尝试添加 nil 作为值,这些通常会抛出异常。 相反,您可以使用单例 +[NSNull null],它除了充当“此空间故意留空”对象之外不执行任何操作。

有了这两种武器可供您使用,就没有理由编写自定义类的空实例了:-)

There are two things which can help here. The first is nil, the Objective-C equivalent of the Java NULL pointer - it can actually receive messages and respond to them. It will always return nil if the return value is an object, and 0 if the return value is some primitive type. Therefore if the Null behaviour of your object is "do nothing" you can easily just use nil as the Null value.

The other thing which is helpful is for when you need to store a placeholder or null value in a container object - these usually throw exceptions if you attempt to add nil as a value. Instead you can use the singleton +[NSNull null], which does nothing except act as a "this space intentionally left blank" object.

With these two weapons at your disposal there should be no reason to write a null instance of a custom class :-)

金橙橙 2024-07-23 21:06:47

对于您的 Response.YES 和 Response.NO,我假设您确实想要更改实例,而不是仅仅将所有 Response 属性设置为只读。

Cocoa 中的一个常见模式是同时拥有类的不可变版本和可变版本(NSArray 与 NSMutableArray)。 对于您的响应示例,拥有一个具有静态 YES 和 NO 方法的不可变 Response 类,以及一个在您确实希望对象更改设置器时公开 setter 的 MutableResponse 子类是有意义的。 这涵盖了你的第二个例子吗?

For your Response.YES and Response.NO, I assume you have instances that you do want to change, rather than just making all Response properties read-only.

A common pattern in Cocoa is to have both immutable and mutable versions of a class (NSArray versus NSMutableArray). For your response example, it would make sense to have an immutable Response class that has the static YES and NO methods, and a MutableResponse subclass that exposes setters for those times where you do want objects to change them. Does this cover your second example?

沉鱼一梦 2024-07-23 21:06:47

我认为没有一种简单的方法可以提供这种实现。 你要求在 Objective-C 中实现 Java 的语言特性 - 你可以做到,但你必须自己编写 Java 运行时中的代码 - 没有什么可以阻止你这样做,但它是 这有点

像问“如何在 Cocoa 中显示 Windows 风格的‘每个窗口一个菜单’UI”——你可以做到,但它不是从框架免费提供的。 或者,“如何在 Java 中轻松实现 Objective-C 的 nil 指针处理?”

如果你真的想看到这种类型的功能,我认为你应该遵循 NSArray/NSMutableArray 设计模式。 声明一个可以处理所有特殊情况的超类:

@interface NullPizza : NSObject
{
}
- (BOOL)areYouANullPizza;
@end

然后使用真正的 Pizza 进行子类化并包含 newNullPizza 类方法(这只是语法糖):

@interface Pizza : NullPizza
{
}

+ (Pizza*)Null;
@end

@implementation Pizza
+ (Pizza*)newNullPizza
{
    return [[NullPizza]alloc init]; // Singleton code left as an exercise.
}

- (BOOL)areYouANullPizza;
{
    return NO;
}
@end

请注意,如果您想实现 +(Pizza*)NULL Pizza 上的 方法,您应该自动释放您创建的新 NullPizza。

免责声明,我直接将这段代码输入到 SO 中。 如果它能编译,我会感到惊讶,但你明白了。

I don't think there is an easy way to provide this implementation. You're asking for something that is a language feature of Java to be implemented in Objective-C - you can do it but you have to write the code that is in the Java runtime yourself - there is nothing to stop you doing this but it's not something the language has built in.

It's a bit like asking "How do I show a Windows style 'one menu per window" UI in Cocoa' - you can do it but it's not provided for free from the framework. Or, "how can I easily implement Objective-C's nil pointer handling in Java?"

If you really want to see this type of functionality I think you should follow the NSArray/NSMutableArray design pattern. Declare a superclass that can handle all of your special cases:

@interface NullPizza : NSObject
{
}
- (BOOL)areYouANullPizza;
@end

and then subclass with your real Pizza and include a newNullPizza class method (which is just syntax sugar):

@interface Pizza : NullPizza
{
}

+ (Pizza*)Null;
@end

@implementation Pizza
+ (Pizza*)newNullPizza
{
    return [[NullPizza]alloc init]; // Singleton code left as an exercise.
}

- (BOOL)areYouANullPizza;
{
    return NO;
}
@end

Note that if you wanted to implement a +(Pizza*)NULL method on Pizza you should autorelease the new NullPizza you create.

Disclaimer, I typed this code straight into SO. I'd be surprised if it compiles but you get the idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文