Objective-C有类似C ++虚函数的东西吗?

时间:2011-09-08 11:52:23

标签: objective-c dynamic properties virtual-functions

在objective-c中,可以将@dynamic添加到属性中。

这对普通实例方法也有可能吗?

修改 我想我还不够清楚。

我想做以下事情:

@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 个答案:

答案 0 :(得分:5)

如果您的意思是“我如何声明方法,但不提供我将在运行时提供的定义?”然后它很容易,只需使用一个类别。像这样:

@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,除非你以某种方式为它提供了一个实现,否则它会因“无法识别的选择器”而崩溃。当然,您可以通过调用respondsToSelector来测试它:。

相关地,如果您正在寻找一个近似等效的基类纯虚方法,我建议提供一个空实现,如果它没有被子类覆盖,则在调用时断言。你可以这样做:

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 ;

当然,这不会在编译时提醒你注意问题,但它总比没有好。

HTH

答案 1 :(得分:2)

@dynamic只是编译器的一条指令:“不要为这个属性生成访问器,我将自己提供。”

将@dynamic与其他方法一起使用是没有用的,因为编译器不为你生成除访问器之外的任何方法,当然你还是提供其他方法。

你想要完成什么?

答案 2 :(得分:2)

我想你可能会问如何声明一个稍后会在其他地方实现的方法。

Objective-C方法是使用Protocols

您通常在头文件

中声明这样的协议
@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
}

这样的例子都在Cocoa上 - 它的类可以提供它想要移植到它的委托的动作列表,委托采用协议并提供那些委托的实现方法。然后,调用对象可以检查此委托是否在运行时响应这些方法,如上所述,并调用这些方法来执行操作,或者在需要的地方提供信息。

这在Objective-C中使用了很多,其中类提供了他们希望其他类执行的方法列表,这与虚函数不同,其中类声明了它希望子类为其提供实现的函数。特别是作为组合比语言中的继承更受青睐。您只需创建另一个可以执行相同操作的类,而不是创建一个子类来提供实现,而是在类中添加对该类的引用。