2011-09-08 41 views
0

在objective-c中,可以将一个@dynamic添加到属性中。Objective-C有类似C++虚函数的东西吗?

这对普通的实例方法也是可行的吗?

编辑 我觉得我还不够清楚。

我要做到以下几点:

@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 

回答

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所以它必须实现它的执行协议中的类时声明的一致性,但它可以选择是否不实施

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

再次optionalMethod

现在,需要对象的实例,以符合协议的任何类可以声明此,例如,在接口,这是在编译期进行检查

要确保贴合类实现@optional方法,我们可以用这个结构轻巧的这个

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

例子遍布可可 - 这是一类可以提供一个列表它希望将其用于委托的操作,委托人采用协议并提供这些委托方法的实现。然后调用对象可以检查这个委托是否在运行时响应这些方法,如上所述,并调用这些方法来执行操作,或者在需要时提供信息。

这在Objective-C中用得相当多,其中类提供了一些他们希望其他类可以执行的方法列表,这与虚拟函数不同,虚函数是类声明函数,它希望子类提供实现。特别是因为组合在语言上优于继承。而不是创建一个提供实现的子类,而是创建另一个可以做同样事情的类,并在该类中添加对该类的引用。

+1

协议类似于Java/C#接口,在C++中,它们最接近于没有数据成员的抽象类以及所有纯虚拟方法。我认为一个协议仅仅是为了在运行时提供实现的单个类声明一个方法而有点矫枉过正。就个人而言,我会为多个类将实现(或不是)相同方法的情况保存协议。 – ipmcc

+1

想想iOS,其中委托用于将数据从堆栈顶部的视图传递到视图控制器。一个常见的做法是委派,这只是一个阶层与另一个阶层之间的渠道。 – Abizern

2

@dynamic仅仅是写着编译器指令:“不要打扰产生存取该物业的,我我会提供我自己的。“

对其他方法使用@dynamic不会有帮助,因为编译器不会为您生成除访问器以外的任何方法,当然您仍然提供其他方法。

你想完成什么?

+0

我想要一个没有实现它的方法的声明。它的实现是在运行时提供的。像一个虚拟的C++函数。 –

+0

@Mats每个Objective-C方法都是C++的虚拟方法。你是否指C++中的纯虚拟成员函数? – Yuji

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

相关问题