Шаблон нулевого объекта в Objective-C - PullRequest
2 голосов
/ 08 апреля 2009

В Java очень легко закодировать следующий дизайн:

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

    /* actual/abstract implmentations */
}

Каков предпочтительный метод для достижения того же эффективного сценария в Objective-C? Мне не удалось найти какую-либо документацию по этому вопросу, и я пробовал пару различных сценариев с static const, #define и т. Д., Но ни один из них, похоже, не сработал так же, как метод Java выше.

Я бы не хотел писать конкретный класс NullPizza, в котором есть статический метод для получения экземпляра синглтона, так как для него более подходящим является какое-то конечное свойство / поле интерфейса самого высокого уровня. (Пицца, в данном случае.)

Редактировать: Хотя я понимаю, как именно будет обрабатываться шаблон NULL, благодаря уникальному методу Obj-C для обработки вызовов методов в 'nil', как насчет других статических общих экземпляров, таких как Response.YES? и Response.NO? (См. Комментарии для обсуждения.)

Ответы [ 4 ]

12 голосов
/ 08 апреля 2009

Нет необходимости в этом типе шаблона в Objective-C, потому что он не считается ошибкой времени выполнения для сообщения нулевого экземпляра класса. Если у метода есть определенный тип возвращаемого значения, существуют определенные возвраты из сообщения nil-объекта (например, методы, которые возвращают целое число, возвращают 0 при обмене сообщениями nil-объекта).

2 голосов
/ 08 апреля 2009

Здесь могут помочь две вещи. Первый - nil, эквивалент Objective C указателя Java NULL - он может фактически получать сообщения и отвечать на них. Он всегда будет возвращать nil, если возвращаемое значение является объектом, и 0, если возвращаемое значение имеет некоторый примитивный тип. Поэтому, если для вашего объекта установлено нулевое поведение «ничего не делать», вы можете просто использовать nil в качестве значения Null.

Другая полезная вещь - это когда вам нужно сохранить заполнитель или нулевое значение в объекте контейнера - они обычно генерируют исключения, если вы пытаетесь добавить nil как значение. Вместо этого вы можете использовать синглтон +[NSNull null], который ничего не делает, кроме как действует как объект «это пространство намеренно оставлено пустым».

При наличии этих двух видов оружия не должно быть оснований для написания нулевого экземпляра пользовательского класса: -)

0 голосов
/ 02 июня 2009

Я не думаю, что есть простой способ обеспечить эту реализацию. Вы запрашиваете что-то, что является языковой функцией Java, для реализации в Objective-C - вы можете сделать это, но вы должны сами написать код, который находится во время выполнения Java - ничто не мешает вам делать это, но не то, что встроено в язык.

Это немного похоже на вопрос «Как мне показать стиль интерфейса Windows« по одному меню на окно »в Какао» - вы можете сделать это, но это не предоставляется бесплатно из фреймворка. Или, «как я могу легко реализовать обработку нулевого указателя в Objective-C в Java?»

Если вы действительно хотите увидеть этот тип функциональности, я думаю, вы должны следовать шаблону проектирования 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. Я был бы удивлен, если бы он компилировался, но вы поняли.

0 голосов
/ 29 мая 2009

Для ваших Response.YES и Response.NO я предполагаю, что у вас есть экземпляры, которые вы хотите изменить, вместо того, чтобы просто сделать все свойства Response доступными только для чтения.

Распространенный шаблон в Какао - иметь как неизменяемые, так и изменяемые версии класса (NSArray против NSMutableArray). Для вашего примера ответа было бы целесообразно иметь неизменный класс Response, имеющий статические методы YES и NO, и подкласс MutableResponse, который предоставляет сеттеры для тех случаев, когда вы хотите, чтобы объекты их изменяли. Это охватывает ваш второй пример?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...