how can I automatically get the same methods in multiple classes with different inheritance? - objective-c

I have a singleton class that I want accessible via a helper method on multiple classes...
One of my classes inherits from CCLayer:
#interface Game : CCLayer
the other NSObject:
#interface Question : NSObject
... So my thought was to create a class:
#import "Storeizer.h"
#implementation Storeizer
-(StorageMechanism*)store {
return [StorageMechanism sharedStorageMechanism];
}
#end
And have both Game and Question classes inherit from Storeizer so that they can automatically have a self.store convenience method.... However, this is a problem since my other classes already inherit from different objects (CCLayer and NSObject). So, I am a little confused how to proceed, and am wondering if this convenience method is more trouble than it's worth. I just come from a world where I hate to have redundant code, and having multiple classes calling [StorageMechanism sharedStorageMechanism] feels a little unfriendly on the eyes (to me at least).
So, how can I solve this problem?

Add a category to NSObject, and import the header of the category where you are using these methods.

Related

Objective-C : Accessing fields in implementation

Is it possible to fields defined only in implementation but not in interface definition ?
#interface MyInterface .... #end --> dict not defined here!!!
#implementation MyInterface
...
NSDictionary *dict;
...
#end
In this case if somewhere I somehow accessed to this class, can I access to the dict or should I create a getter just like in Java ?
Edit after #Rob's answer
Thanks for the answer Rob, I wish I have the implementation of these interface and classes. Instead I am trying to bind two different libraries ( I know it is reallllly bad as architectural point of view but this is where I end up).
Basically, I am in react-native world. And we are using react-native-video as our player layer. But since AVPlayer does not support some subtitle types our head company sent us a library that needs a player instance and a view instance to draw subtitle on the view. I believe they will bind to events of the player and draw sub titles based on player states.
So react-native-video is in this github repo with the interface and implementation.
I find the UIView that includes the properties and casted it to the object itself RTCVideo in this case). But now I am stuck. I can go and change some stuff as per your suggestion in the "Development Pods" to be able to access but this is my last bullet :) I prefer to convince these two libraries in a friendly way :)
Yes, but the above syntax isn't what you want. The modern way to do this is with a class extension.
Your header file is the same:
#interface MyInterface
#end
But in your .m file, you create an extension by appending ():
#interface MyInterface ()
#property (nonatomic, readwrite) NSDictionary *dict;
#end
Now, inside your .m file, you can access self.dict normally, but outside of your .m file it won't appear available.
For full details, see Programming with Objective-C: Class Extensions Extend the Internal Implementation.
The syntax you've written actually creates a static (global) variable called dict that isn't tied to any instance.
It is possible to create raw instance variables using a {...} syntax, either on the extension or on the implementation, but this isn't used that often today, except for managing raw buffers that you don't want accessors for. The syntax is either:
#interface MyInterface () {
NSDictionary *_dict;
}
...
#end
or on the implementation:
#implementation MyInterface {
NSDictionary *_dict;
}
...
#end
But I recommend simple extensions with properties any time you can. And if you are considering creating an accessor for it, you definitely want to use #property and let the system do it for you.
If I understand your edits correctly, you're trying to read the internal ivars of an object that doesn't expose them with an accessor, correct? I believe specifically you want to access _player.
There's several common ways to do that. The key feature you want is Key-Value Coding.
The simplest approach for this problem is -valueForKey:
AVPlayer *player = [view valueForKey:#"player"];
The first thing -valueForKey: looks for is _<key>, and if it's just an object pointer (as in this case), it just returns it.
(This can be broken if a class return false for +accessInstanceVariablesDirectly, but the default is true, and it's unusual to override this.)
Another very common approach is to just declare any methods you know exist as a category. (This won't work for _player, since it's not a method, but in case you need similar things.) Imagine you wanted to call the "private" method -removePlayerTimeObserver. In your .m file, just say you know about it using a category:
#interface RCTVideo (PrivateMethods)
- (void)removePlayerTimeObserver;
#end
And since you know about it, you can call it:
[video removePlayerTimeObserver];
If you're wrong, and that method doesn't really exist, then the program will crash. In Objective-C, almost all rules are advisory. You can break them if you want to. ObjC programmers tend to be big rule-followers because otherwise the program crashes and ObjC has very clear rules that are pretty easy to follow. It's not because the system forces us to.

Questions on creating an empty template class just for the purpose of subclassing

I am trying to create a plugin system within my objective-c project so I can just create a class that follows certain convention and it would work right out of the box.
These classes contain common headers (which includes protocols and categories), and also needs to follow the included protocols. But other than that each class is very distinct and don't share any code.
I don't want to have to write the same lines every time I need to write a plugin so thought about creating a base class like this:
#import <Foundation/Foundation.h>
#import "Helper.h"
#import "ComponentProtocol.h"
#import "UIView+Extension.h"
#interface Component : NSObject <ComponentProtocol>
+ (UIView *)someProtocolFunction;
#end
The class has NO implementation
And then whenever I need to create one of these classes I would just create a class that looks like this:
#import "Component.h"
#interface CustomComponent : Component
#end
So I have two questions:
Is this an OK thing to do? The base class won't have a single line of code in it since I'm just using it as a template. Or if there's a better way to do this?
As you can see in the code, the protocol requires a class method. I don't know how I would go about this in the subclasses. If it was an instance method I could just call [super someProtocolFunction]; and then add the subclass-specific logic, but I don't know how this would work in a class method setting.

How to override a function that is part of a category's original class?

for example let's say i have a class car with the following .h:
Car.h
#interface Car : Automobile
#property Engine * V6;
-(void)igniteEngine:(int) key;
-(void)StopEngine;
#end
and now I have a category Car(Test) with the .m file
Car(Test).m
#implementation Car(Test){
Oil * testingOil;
}
...
#end
and i want to override a function in the following way
-(void)igniteEngine:(int) key //inside test
{
[self applyTestingOil];
[(reference to original class) igniteEngine:key];
}
how would I go by doing this?
if there is a different way of approaching this problem that would also be helpful
Overriding a method in a category is not an option, as the behavior at runtime will be undefined: you have no way to know which of the base class or category implementation will be executed.
See Avoid Category Method Name Clashes.
If possible, the simplest way to do this is to subclass the base class, and override the method there.
Is subclassing is not an option, you can use method swizzling. This will exchange the method implementation with your own at runtime.
But as Mattt put it: "Swizzling is widely considered a voodoo technique", so I'd avoid it if I could.
If you think swizzling could solve your problem, and you're ready to "take the risk", take a look at JRSwizzle, which will handle most of the boilerplate for you.
Considering your ivar Oil * testingOil;, subclassing is again the only simple option. As rmaddy said in the comments, categories does not allow you to add ivars to the class. You'll need to use Associated Objects for this. And well... it's not pretty.

Interface is declared twice? - Objective-C

I'm new to Objective-C and am looking through many examples to wrap my head around it.
I came across this code:
#interface ImagePickerHelper : NSObject <UIImagePickerControllerDelegate, UIPopoverControllerDelegate, UINavigationControllerDelegate>
//Blah Blah
#end
#interface ImagePickerHelper ()
//Blah Blah
#end
On googling, I came to know that they specify the superclass and delegates (about which, incidentally, I know zilch) after the interface name.
But why is the interface declared twice here?
No, it is not declared two times, it is a Class interface (an anonymous category) that it is created to hold methods that you want to keep private in your class, for methods that you don't want other class to see or to interact with ..
People often declare a standard category with a name(usually "private") to hold private methods, but
the main advantage of using an anonymous category over a named category is that the compiler will complain if you do not implement a method declared in the anonymous category.
I have noticed that it is created by default from XCode 4.3 onwards .
Putting methods into this extension Class it is like declaring private methods in Java or C++ ...
The second "#interface" you see (probably in a .m file) is a class extension, and probably meant for private methods (well, private in the sense that the compiler will generate "may not respond to" warnings).

How to not duplicate code in Objective-C? (a.k.a. multiple inheritance)

When you have an UIViewController and UITableViewController classes and you wanted to let these two do some common stuff in their - (void)viewDidLoad how could you achieve this in Objective-C without actually duplicating your code?
I tried to create MyUIViewController inheriting UIViewController and implement viewDidLoad in there. This perfectly works with UIViewController classes obviously, but won't work in UITableViewController, since I can't simply replace #interface MyTableViewController : UITableViewController with #interface MyTableViewController : MyUIViewController.
I believe this topic is about "multiple inheritance" in Objective-C language, but other than figuring out what's different in Objective-C, I'd really like to know how to do guys do such thing?
This thread has some good information. One of your main options is to make a class with that shared functionality and hold it as an instance variable, then forward messages to it in forwardInvocation.