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

发布于 2024-12-03 10:50:44 字数 376 浏览 2 评论 0原文

在 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

In objective-c it is possible to add a @dynamic to a property.

Is this also possible for normal instance methods?

EDIT
I think i wasn't clear enough.

I want to do the following:

@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

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

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

发布评论

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

评论(3

等风也等你 2024-12-10 10:50:45

如果您的意思是“如何声明一个方法,但不提供随后在运行时提供的定义?”那么就很简单了,只要使用一个类别即可。像这样:

@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 ;

当然,这不会在编译时提醒您出现问题,但总比没有好。

华泰

If you mean "How can I declare a method, but not provide a definition which I will subsequently provide at runtime?" Then it's easy, just use a category. Like this:

@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

The compiler will not complain, however if you call -myDynamicMethod at runtime, unless you have provided an implementation for it somehow, it will crash with "unrecognized selector." You can, of course, test for that at runtime by calling respondsToSelector:.

Relatedly, if you're looking to do a near-equivalent of a base class pure virtual method, I would recommend providing an empty implementation that asserts when called if it has not been overridden by a subclass. You can do that like so:

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 ;

Of course, that won't alert you to problems at compile time, but it's better than nothing.

HTH

陌伤浅笑 2024-12-10 10:50:45

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

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 的实现,因此它必须实现它,但它可以选择是否或 现在,任何需要

对象实例符合协议的类都可以声明它,例如在接口中

@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 中被大量使用,其中类提供了它们希望其他类执行的方法列表,这与虚函数不同,在虚函数中,类声明它希望子类为其提供实现的函数。特别是在语言中,组合比继承更受青睐。您无需创建子类来提供实现,只需创建另一个可以执行相同操作的类,然后在该类中添加对该类的引用即可。

I think you might be asking how to declare a method that will be implemented some time later somewhere else.

The Objective-C way to do that is to use Protocols.

You declare a protocol like this, usually in a header file

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

This declares two methods, one which is optional and one is required. To use this protocol you declare the conformance when declaring the class that will implement the protocol

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

This new class is checked at compile time for the implementation of requiredMethod so it has to implement it, but it can choose whether or not to implement the optionalMethod

Now, any class that requires instances of objects to conform to the protocol can declare this, for example, in the interface

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

Again, this is checked at compile time

To make sure that the conforming class implement the @optional methods, we can use this handy structure

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

Examples of this are all over Cocoa - it's a class can provide a list of actions that it would like to farm out to it's delegate, the delegate adopts the protocol and provides the implementations of those delegate methods. The calling object can then check if this delegate responds to those methods at runtime as I've described above, and call those methods to perform actions, or provide information where ever it needs to.

This is used quite a lot in Objective-C, where classes provide a list of methods that they would like some other class to perform, unlike virtual functions, where a class declares functions it wants subclasses to provide implementations for. Particularly as Composition is favoured over inheritance in the language. Rather than create a subclass to provide an implementation, you just create another class that can do the same thing, and add a reference to that in the class instead.

[旋木] 2024-12-10 10:50:45

不。

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

将 @dynamic 与其他方法一起使用不会有帮助,因为编译器不会为您生成除访问器之外的任何方法,当然您无论如何都会提供其他方法。

你想实现什么目标?

No.

@dynamic is just an instruction to the compiler that says: "Don't bother generating accessors for this property, I'm going to provide my own."

Using @dynamic with other methods wouldn't be helpful because the compiler doesn't generate any methods other than accessors for you, and of course you're supplying the other methods anyway.

What are you trying to accomplish?

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