Есть ли в Objective-C что-то вроде виртуальных функций C ++? - PullRequest
0 голосов
/ 08 сентября 2011

В target-c можно добавить @dynamic к свойству.

Возможно ли это для обычных методов экземпляра?

EDIT Я думаю, что я не был достаточно ясен.

Я хочу сделать следующее:

@interface MyClass
@property (retain) NSObject *somePropertyObject;
- (void) myMethod;
@end

@implementation MyClass

@dynamic somePropertyObject;

//Make myMethod dynamic. I do not want to implement it. Like C++ Virtual

@end

Ответы [ 3 ]

5 голосов
/ 08 сентября 2011

Если вы имеете в виду «Как я могу объявить метод, но не предоставить определение, которое я впоследствии предоставлю во время выполнения?» Тогда это просто, просто используйте категорию. Как это:

@interface MyObject : NSObject

// Methods I'll define
- (void)doFoo;

@end

@interface MyObject (DynamicallyProvidedMethods)

// Methods I won't
- (void)myDynamicMethod;

@end


@implementation MyObject 

// Methods I'll define
- (void)doFoo
{
}

@end

Компилятор не будет жаловаться, однако, если вы вызовете -myDynamicMethod во время выполнения, если вы не предоставили для него реализацию каким-либо образом, он завершится с «нераспознанным селектором». Конечно, вы можете проверить это во время выполнения, вызвав responsedsToSelector:.

Соответственно, если вы хотите сделать почти эквивалентный чистый виртуальный метод базового класса, я бы порекомендовал предоставить пустую реализацию, которая при вызове выдает запрос, если он не был переопределен подклассом. Вы можете сделать это так:

NSAssert((class_getInstanceMethod([self class], _cmd) == class_getInstanceMethod([MyObject class], _cmd)),
    @"Subclass of %@ must override -%@", 
    NSStringFromClass([MyObject class]), 
    NSStringFromSelector(_cmd));

// ...where overridesSelector:ofBaseClass: looks like: 
//
//     return ;

Конечно, это не предупредит вас о проблемах во время компиляции, но это лучше, чем ничего.

НТН

2 голосов
/ 08 сентября 2011

Я думаю, вы можете спросить, как объявить метод, который будет реализован через некоторое время где-нибудь еще.

Способ Objective-C для этого - использовать Протоколы .

Вы объявляете такой протокол, обычно в заголовочном файле

@protocol MyProtocol <NSObject> {
@optional
    - (void)optionalMethod;
@required
    - (void)requiredMethod;
}
@end

Здесь объявляются два метода, один из которых является необязательным, а другой - обязательным.Чтобы использовать этот протокол, вы декларируете соответствие при объявлении класса, который будет реализовывать протокол

@interface MyConformingClass : NSObject <MyProtocol> {
}
// you don't have to redeclare methods that are declared in the protocol
@end

. Этот новый класс проверяется во время компиляции для реализации requiredMethod, поэтому он должен его реализовать, но онможете выбрать, следует ли реализовывать optionalMethod

Теперь любой класс, которому требуются экземпляры объектов для соответствия протоколу, может объявить это, например, в интерфейсе

@interface RequiringClass : NSObject {
    MyConformingClass <MyProtocol> *conformingClassObject;
}
…
@end

Опять же, это проверяется во время компиляции

Чтобы убедиться, что соответствующий класс реализует методы @optional, мы можем использовать эту удобную структуру

if [conformingClassObject respondsToSelector:@selector(optionalMethod)] {
    [conformingClassObject optionalMethod];
} else {
    // Do something here because the optional method isn't provided
}

Примеры этого по всему Какао- этот класс может предоставить список действий, которые он хотел бы передать своему делегату, делегат принимает протокол и предоставляет реализации этих методов делегата.Затем вызывающий объект может проверить, отвечает ли этот делегат на эти методы во время выполнения, как я описал выше, и вызвать эти методы для выполнения действий или предоставить информацию, когда это необходимо.

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

2 голосов
/ 08 сентября 2011

номер

@dynamic - это просто инструкция для компилятора, которая гласит: «Не беспокойтесь о генерации методов доступа для этого свойства, я предоставлю свой собственный».

Использование @dynamic с другими методами не поможет, поскольку компилятор не генерирует для вас никаких методов, кроме методов доступа, и, конечно, вы все равно предоставляете другие методы.

Чего вы пытаетесь достичь?

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