I hope the title is precise enough.
I was wondering, how I can pass a interface implementation to an object in objc language.
In java it would look like:
public interface MyInterface {
void onData();
}
The implementing class
public class ImplementMyInterface {
// ...
// other methods
///
void registerInterface(){
MyInterface myInterface = new MyInterface(){
#Override
public void onData(){
// process data here within the class
}
};
}
}
And in objc?
id myinterface.
How to implement it in the class?
Is there only the possibility to let the class inherit the interface?
Like
interface MyInterface : NSObject
and the implementing class
MyImplementingClass : MyInterface
Or is there another possibility?
Thank you in advance
Objective-C has anonymous functions (blocks), but it doesn't have anonymous classes. So, the only way to implement a protocol (which is the objective-c term for an interface) is to make some class conform to that protocol (using your terminology, make that class "inherit" from that protocol) and add a protocol implementation inside that class' implementation.
I was able to solve my problem.
I was only able to import the MyInterface header file in my ImplementMyInterface.m file, but rather in the ImplementMyInterface.h file.
So everything I could do was inside the ImplementMyInterface.m file.
// ImplementMyInterface.m
#import "MyInterface.h"
// inner class
#interface MyInternalInterface : NSObject<MyInterface>
#property (retain) ImplementMyInterface * implementation;
#end
// the actual class
#implementation ImplementMyInterface
MyInternalInterface * _internalInterface;
+(instancetype) build {
// construct myself
ImplementMyInterface * implementatMyInterface = [[ImplementMyInterface alloc] init];
// init inner class object
_internalInterface = [[MyInternalInterface alloc] init];
// register myself
[_internalInterface setImplementation:implementatMyInterface];
return implementatMyInterface;
}
- (NSString *) theActualData {
return #"The actual data";
}
// end of implementation class
#end
// implementation of inner class
#implementation MyInternalInterface
#synthesize implementation;
- (NSString *) onData {
if(implementation != nil)
return [implementation theActualData];
return #"";
}
// end of ImplementMyInterface.m
Related
I am using Objective-C to consume a Swift Code that I am turning into a Framework/SDK eventually.
I can not invoke the class Methods specifically to Objective-C, and I am getting this error
No visible #interface for 'class' declares the selector 'method'
Swift File
public class Example {
public class func testOne() -> NSString {
return "testOne";
}
public func testTwo() -> NSString {
return "testTwo";
}
}
Objective-C File
#import <ProjectModuleName-Swift.h>
#interface ...
#end
#implmentation ...
- (void) testing {
Example *example = [[Example alloc] init];
NSString *testOne = [example testOne]; // does not work ; No visible #interface for 'Example' declares the selector 'testOne'
NSString *testTwo = [example testTwo]; // does work
}
#end
Obviously, by declaring class func it should require a different way to invoke it through Objective-C, but I have not seen any docs on this topic.
An example or help would be much appreciated.
Class methods are called on the class, not instances of the class:
NSString *testOne = [Example testOne];
NSString *testTwo = [Example testTwo];
I created a protocol, called EventListener:
#protocol EventListener
...
#end
I also have class, Processor, like:
// Processor.m
#synthesize listeners = _listeners; //#property NSMutableArray* in Processor.h
- (id) init {
self = [super init];
self.listeners = [[NSMutableArray alloc] init]; //init with empty array
return self;
}
- (void) addListener:(id<EventListener>)listener {
[self.listeners addObject:listener];
}
I have another class, called Plugin:
#interface Plugin : NSObject <EventListener> { ... }
...
#end
and in its implementation, I perform:
// Plugin.m
[self.processor addListener:self];
and get warning that
incompatible pointer types sending Plugin* sending to parameter of type Listener*
What I've done wrong?
I'm coming from java world and assume that because my Processor implements protocol it should be type of Listener, smith like:
interface Listener {
}
class Processor {
List<Listener> listeners = new ArrayList<Listener>();
void addListener(Listener listener) {
listeners.add(listener);
}
}
class Plugin implements Listener {
Processor processor = new Processor();
void method() {
processor.addListener(this);
}
}
In Objective-C, classes and protocols are completely separate things and — unlike Java's classes and interfaces — have distinct syntax.
If you wanted to accept any class which is, or is a descendant of, the class Listener then the parameter would be:
Listener *
If you wanted to accept any class that implements the protocol EventListener then the parameter would be:
id <EventListener>
As id means "any class type" and the <EventListener> adds that whatever is passed should implement that protocol.
If you wanted to accept only those of Listener and its subclasses that implement EventListener then the parameter would be:
Listener <EventListener> *
That contrasts with Java where you'd take the interface type directly and not specify any class type constraints.
You can get the same warning when you declared
#interface SomeClass <SomeProtocol> : NSObject
#end
instead of
#interface SomeClass : NSObject<SomeProtocol>
#end
The first syntax is correct but it has no sense.
I have class tructure like this
#interface SuperClass: NSObject
+ (void) someName;
#end
#interface MyClass: SuperClass
#end
There is the case that i only want to call the someName if it is a class method of MyClass not MyClass's superclass. Since [[MyClass class] respondsToSelector:#selector(someName)] return YES if a class or its super response to the selector. How to tell that MyClass doesnt contain tosomeName?
In my application i want to print the string that contains chains of string return from a class method.
Take abve class structure as a example, i want to print something like:
somenameFromSuper.somenameFromClass.someNameFromeSubClass.
if a class doesnot implement someName method, i want to replace it by `notavailable, for ex:
somenameFromSuper.notavailable.someNameFromeSubClass.
_Bool class_implementsMethodForSelector( Class cls, SEL selector )
{
unsigned methodsCount;
Method* methods = class_copyMethodList(cls, &methodsCount);
for (unsigned methodIndex=0; methodIndex<methodsCount; methodIndex++)
{
if (method_getName(methods[methodIndex]) == selector)
{
break;
}
}
free(methods);
return methodsIndex<methodsCount;
}
…
Class classToTest = …;
classToTest = object_getClass(classToTest); // For checking class methods
if (class_implementsMethodForSelector(classToTest, #selector(someName))
{
…
}
else
{
…
}
Typed in Safari.
Edit: Made a function of it. Still typed in Safari.
How to reference to a class (not an instance of it!) which implements a specific protocol?
+(id<Data>) dataForName:(NSString *)name {
id<DataManager> manager = SpecializedDataManager; // <-- which datatype does "manager" have to be?
return [[manager sharedManager] get:name]; //Getting data over a singleton of manager
}
Where Data and DataMangerare protocols and SpecializedDataManager is a class implementing the DataManager protocol.
I haven't tried this myself, but you should be able to use a pointer-to-class, although I doubt that you could specify that the class must implement a certain protocol:
static Class manager = NULL;
+ (void)someInitMethod
{
manager = [SpecializedDataManager class];
NSAssert([manager conformsToProtocol:#protocol(DataManager)], #"Achtung!");
}
If I understood you correct you want to write something like this:
id<SomeProtocol> someObject = AnotherObjectConformingThisProtocol;
Class class = [(NSObject*)SomeObject class];
if ([someObject isKindOfClass:[AnotherObjectConformingThisProtocol class]]) {}
if (class == [AnotherObjectConformingSomeProtocol class]) {}
If no - please clarify what exactly do you mean.
UPDATE: I've read your comment near another post and got it:
Create wrapper classes for your DataManager and Data protocols:
#interface DataClass : NSObject <Data>
#end
#interface DataManagerClass : NSObject <DataManager>
#end
And use code like this:
+(DataClass*) dataForName:(NSString *)name {
DataManagerClass* manager = SpecializedDataManager; // <-- which datatype does "manager" have to be?
return [[manager sharedManager] get:name]; //Getting data over a singleton of manager
}
Is this what you're looking for:
+(id<Data>) dataForName:(NSString *)name {
Class<DataManager> manager = [SpecializedDataManager class];
return [[manager sharedManager] get:name];
}
I'm fairly new to Objective-C and wondering if it's possible to type objects as their supertype without receiving compiler warnings when assigning them, or if there is a recognised way of achieving the same thing?
I realise that this is what type id is for but I have a base class with synthesized properties and if I try to use id I get a build error "request for member 'x' in something not a structure or union", presumably because dynamic typing is fine for sending messages to an object but not for accessing synthesized properties.
For example in Java I might have:
public abstract class A {
public function doSomething() {
//some func
}
}
public class B extends A {
public function doSomething() {
//override some func
}
}
public class C extends A {
public function doSomething() {
//override some func
}
}
//and in my main class:
A objB = new B();
A objC = new C();
//the purpose of all of this is so I can then do:
A objHolder;
objHolder = objB;
objHolder.doSomething();
objHolder = objC;
objHolder.doSomething();
I currently have the above working in Objective-C but with a compiler warning: "assignment from distinct Objective-C type"
OK, here is the Objective-C interfaces, I can add the implementations if you want. It's a composite pattern:
//AbstractLeafNode
#import <Foundation/Foundation.h>
#interface AbstractLeafNode : NSObject {
NSString* title;
AbstractLeafNode* parent;
}
#property (nonatomic, retain) NSString* title;
#property (nonatomic, retain) AbstractLeafNode* parent;
#end
//Page
#import "AbstractLeafNode.h"
#interface Page : AbstractLeafNode {
//there will be stuff here later!
}
#end
//Menu
#import "AbstractLeafNode.h"
#interface Menu : AbstractLeafNode {
NSMutableArray* aChildren;
}
- (void)addChild:(AbstractLeafNode *)node;
- (void)removeChild:(AbstractLeafNode *)node;
- (AbstractLeafNode *)getChildAtIndex:(NSUInteger)index;
- (AbstractLeafNode *)getLastChild;
- (NSMutableArray *)getTitles;
#end
// I'd then like to do something like (It works with a warning):
AbstractLeafNode* node;
Menu* menu = [[Menu alloc] init];
Page* page = [[Page alloc] init];
node = menu;
[node someMethod];
node = page;
[node someMethod];
// Because of the synthesized properties I can't do this:
id node;
// I can do this, but I suspect that if I wanted synthesized properties on the page or menu it would fail:
node = (AbstractLeafNode*)menu;
node = (AbstractLeadNode*)page;
Sorry, as I was editing the question I realised that I was trying to do it the wrong way round and assign an AbstractLeafNode to a Menu, so the compiler warning completely makes sense. No errors when assigning a Menu to an AbstractLeafNode.
I've been staring at this for too long!