RobertL
RobertL

Reputation: 14874

Call a swift instance function from ObjC when the function's class does NOT inherit from NSObject

Is there a way to do that? What does the call look like supposing the function is "myFunc" in:

@objc class ClassTwo {
    func myFunc() -> () {
        println("class ClassTwo instance function myFunc")
    }
}

IOW calling myFunc from swift looks like the following, so how do I write the same call in ObjC?

ClassTwo().myFunc()

Upvotes: 0

Views: 166

Answers (2)

newacct
newacct

Reputation: 122429

rob mayoff's answer is right. ClassTwo, when bridged to Objective-C, is not declared to have +alloc. However, as part of Objective-C compatibility, all Swift classes in practice have a basic subset of NSObject methods, including +alloc; it's just not publicly declared as such, so the compiler doesn't know.

If you don't want to add another method to your class, another solution is to declare (but not implement) in Objective-C a dummy category that declares +alloc, so that the compiler will think the class has +alloc, and will allow [[ClassTwo alloc] init] to compile.

@interface ClassTwo (Alloc)
+ (instancetype)alloc;
@end

Upvotes: 1

rob mayoff
rob mayoff

Reputation: 385540

Since ClassTwo isn't a subclass of NSObject, it doesn't provide the standard alloc method for allocating an instance. If you're going to create your instances of ClassTwo in Swift and just make existing instances available to Objective-C (by passing them to Objective-C methods or storing them in properties), that's not a problem. But if you want to create instances of ClassTwo in Objective-C, you need to provide a way to do that. Example:

@objc class ClassTwo {
    class func make() -> ClassTwo {
        return ClassTwo()
    }

    func myFunc() -> () {
        println("class ClassTwo instance function myFunc")
    }
}

To use ClassTwo from an Objective-C .m file, you need to import project-Swift.h (where project is the name of your project). Then you can call class methods of ClassTwo and instance methods of ClassTwo instances, like this:

#import "AppDelegate.h"
#import "project-Swift.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    ClassTwo *two = [ClassTwo make];
    [two myFunc];

    return YES;
}

Upvotes: 1

Related Questions