user2517182 user2517182 - 3 months ago 8
Objective-C Question

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.

Answer

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