开发者

Does Objective-C have something like C++ virtual functions?

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


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


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.


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜