user2517182
user2517182

Reputation: 1299

Objective C run 'private' method defined in one .mm file from another .mm file

There are many questions about accessing 'private' (I hear technically there is no such thing as a private method in Obj-C) messages in Obj-C. And there are many questions addressing No visible @interface for SomeClass declares the the selector 'SomeMethod'. However, there is not one that addressed both.

So here is some code. Example.h

#import <Cocoa/Cocoa.h>

@interface Example : NSView

@end

Example.mm

#import "Example.h"
@interface Example()
- (void) printWordOne:(NSString*) firstWorld wordTwo:(NSString*) secondWord;
@end


@implementation Example

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    // Drawing code here.
}

- (void) printWordOne:(NSString*) firstWorld wordTwo:(NSString*) secondWord{
    NSLog(@"The two words are %@ %@", firstWorld, secondWord);
}

@end

ViewController.h

#import <Cocoa/Cocoa.h>
#import "Example.h"
@interface ViewController : NSViewController{
    IBOutlet Example *example;

}

@end

The IBOutlet has been connected in storyboard.

ViewController.mm

#import "ViewController.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Do any additional setup after loading the view.
    [example printWordOne:@"Hello" wordTwo: @"World"];
}

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}

@end

The issue I am having is with this method call. [example printWordOne:@"Hello" wordTwo: @"World"];

The error is No visible @interface for 'Example' declares the selector 'printWordOne:wordTwo'

I need a way to call that function without declaring it in the Example.h file. If I #import Example.mm in my ViewController.mm file I get the following:

duplicate symbol _OBJC_CLASS_$_Example in:
    /path/Example.o
    /path/ViewController.o
duplicate symbol _OBJC_METACLASS_$_Example in:
    /path/Example.o
    /path/ViewController.o
ld: 2 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I know using class_copyMethodList I can get the method list and list that method from ViewController.mm. But again is there anyway to execute the method.

Any help would be greatly appreciated.

Upvotes: 1

Views: 474

Answers (1)

Borys Verebskyi
Borys Verebskyi

Reputation: 4278

You can simply declare category to Example class with private method declaration inside your ViewController.mm:

#import "ViewController.h"

@interface Example()
- (void) printWordOne:(NSString*) firstWorld wordTwo:(NSString*) secondWord;
@end

@implementation ViewController
// ...
@end

Upvotes: 1

Related Questions