Adding own functionality into iOS library - ios

I am using a a library which has quite complicated inherited structure (it consists of a couple of classes, inherited e.g. UITableViewController, UIView, UITableViewCell and others, where some of the classes are used to create custom objects.
I need to add some functionality (to be precise, to implement tap gesture recognizers). The easy solutions is to put a few lines of code into some of the classes of the library.
Generally, I like to have my code separated from libraries code. Is it possible somehow "override" these classes without rewriting them, or to add some extension?
Or the only idea is to write overrides of all the classes generating own classes and tons of useless code?
Or simply add own code to the library?
Additions:
It seems, that categories are right direction, but not particularly, what I want. Here's what I want exactly:
I have a in Class1:
- (void)someMethod {
doThis;
}
And without subclassing // editing the class I would like to transform this to:
- (void)someMethod {
doThis;
andThisToo;
}
Categories add other methods to a class, while I need to add some functionality in already existing method.

You need to use the decorator pattern.
The decorator pattern is used to extend or alter the functionality of
objects at run- time by wrapping them in an object of a decorator
class. This provides a flexible alternative to using inheritance to
modify behaviour.
Since the example you give is pretty sketchy, I can't provide a code example, but check out Wikipedia (http://en.wikipedia.org/wiki/Decorator_pattern)
EDIT
I thought about what you gave and here would be an example of a decorator:
#interface Decorator
#property (strong, nonatomic) id decoratedObject;
- (void)someMethod;
#end
#implementation Decorator
- (void)someMethod {
[self.decoratedObject doThis];
[self andDoThisToo];
}
#end

Related

Understanding the Relation Between Delegation and Protocols

I know there are a lot of similar questions here but I still need some clarification about this concept.
First of all let me start by saying that I do understand what protocols are and how to use them, what I'm having problem understanding is delegation. I do understand that delegation is when one object in a program acts on behalf of another object, sound very simple but hard to see the whole picture.
1- Is delegation just a way to let the compiler know where to look for the code that will be manipulating the object (UITableView etc.)?
2- Do delegation and protocols work together?
3- Can delegation exist without protocols? If yes, can you show me an example.
4- When we declare a protocol and a class conforms to it, can we say that this class conforming to the protocol is delegating on behave of the protocol?
How much of the above is true?
Thanks a lot
1- Is delegation just a way to let the compiler know where to look for the code that will be manipulating the object (UITableView etc.)?
No, delegation is a design pattern. It's just a concept.
2- Do delegation and protocols work together?
Yes they work well together and it's probably the best practice to use protocol for your delegate.
3- Can delegation exist without protocols? If yes, can you show me an example.
Yes you can. Delegation concept is just to remove intellect of an object and put it in the delegate. For exemple an UITableView does not know how many row it has, or what to do when a cell is clicked, so it asks to its delegate.
But the delegate is still another object.
It's better if it implements a particular protocol, but you can do it without.
For exemple :
I've a MyView that is a subview of a MyCustomViewController.
MyCustomViewController.h
- (void)myViewIsTouched;
MyView.h
#property (nonatomic, weak) MyCustomViewController *delegate
MyView.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.delegate myViewIsTouched];
}
There is no protocol in this exemple, but it's still a delegate.
(A better way is still using a protocol instead of declaring the method in the .h)
4- When we declare a protocol and a class conforms to it, can we say that this class conforming to the protocol is delegating on behave of the protocol?
I'm not sure about what're saying. But protocols and delegate are not the same thing. An object implementing a protocol does not mean that it's a delegate.
Delegation allows objects to be able to change their appearance / state based on changes in other parts of your application. Setting a
delegate property on an object will allow the compiler to do some
checks at build-time.
Delegation is often achieved by using protocols, since it allows the
delegate object to be of any class instead of a sub-class of a class
with specific behaviour.
Yes, but this would result in your classes becoming tightly coupled since Foo needs to know about Bar and vice-versa. Using protocols allows you to use any class, hence id property, resulting in a loosely coupled system.
Example:
#class Foo;
#interface Bar : NSObject
- (void)respondToSomeAction:(Foo *)obj;
#end
#implementation Bar
- (void)respondToSomeAction:(Foo *)obj {
NSLog("responding to %#",obj);
}
#end
#interface Foo : NSObject
#property (nonatomic, weak) Bar *delegate
#end
#implementation Foo
- (void)someActionTriggered {
[self.delegate respondToSomeAction:self]
}
#end
When a class conforms to a protocol, the class is compelled to adopt the behaviours of the protocol (implement the methods). It only becomes a delegate if it is given some task to do on behalf of another class, e.g. supply the number of rows in a table.

Extending a method applicable to all UIButtons

I have a UIButton object in my program.
I want to use it like follows
myButton.setImage:blablabla
mybutton.title:.......blabla
...
...
myButton.placeTextBelowImageWithSpacing:12
While calling my method "placeTextBelowImageWithSpacing:12" it must set the image and text accordingly. I have the method ready with me. How can i use it in the above way.
PS: I hate subclassing.
Thanks in Advance
Create a custom subclass of UIButton. I created a button called FinderButton that has an image and a title centered below it. It works great.
If you hate subclassing then you might want to think about a different line of work.
Being an Objective C programmer that hates subclassing is a bit like being a surgeon who hates blood or a farmer who hates dirt. Defining a class hierarchy is one of the main tools for doing development in an OO language like Objective-C.
You can do this by creating a UIButton category:
UIButton+MyCustomMethod.h
#interface UIButton (MyCustomMethod)
- (void)placeTextBelowImageWithSpacing;
#end
UIButton+MyCustomMethod.m
#implementation UIButton (MyCustomMethod)
- (void)placeTextBelowImageWithSpacing
{
// ...
}
#end
You can't. That isn't valid syntax in Objective-C. The closest you can get to that would be to explicitly declare new properties on UIButton that followed your naming convention. Using them would then look like:
myButton.setTitle = #"something"
Then you could override setTitle's setter (setSetTitle:), and making it call setTitle:forControlState:, which I'm assuming is your goal.
But this should only be done through subclassing (learn to love it, it's a big part of OOP), although if you really really want to, you can add the properties in a category using the Objective-C runtime objc_setAssociatedObject() function more info here: Objective-C: Property / instance variable in category

Any gotchas with objc_setAssociatedObject and objc_getAssociatedObject?

I’m looking into ways to add a property (an integer in this case) to all UIView instances, whether they are subclassed or not. Is using objc_setAssociatedObject() and objc_getAssociatedObject() within a category the appropriate, Apple-endorsed way to do this?
I have heard some concerns that this constitutes a “runtime hack,” and can lead to problems that are difficult to track down and debug. Has anyone else seen this type of problem? Is there a better way to add an integer property to all UIView instances without subclassing?
Update: I can’t just use tag, because this needs to be used in a code base that already uses tag for other things. Believe me, if I could use tag for this, I would!
Associated objects come in handy whenever you want to fake an ivar on a class. They are very versatile as you can associate any object to that class.
That said, you should use it wisely and only for minor things where subclassing feels cumbersome.
However, if your only requirement is to add an integer to all UIView instances, tag is the way to go. It's already there and ready for you to use, so there's no need for involving run-time patching of UIView.
If you instead want to tag your UIView with something more than an integer, like a generic object, you can define a category like follows.
UIView+Tagging.h
#interface UIView (Tagging)
#property (nonatomic, strong) id customTag;
#end
UIView+Tagging.m
#import <objc/runtime.h>
#implementation UIView (Tagging)
#dynamic customTag;
- (id)customTag {
return objc_getAssociatedObject(self, #selector(customTag));
}
- (void)setCustomTag:(id)aCustomTag {
objc_setAssociatedObject(self, #selector(customTag), aCustomTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#end
The trick of using a property's selector as key, has recently been proposed by Erica Sadun in this blog post.
Use tag. That's what it was meant for.

How to make My UIControl subclass as superclass of programmatically created UIElements?

In my application I want to associate NSMutableDictionary to all UIElements (UIButton, UILable, etc), I can easily achieve this by subclassing each element, but I just want to know if I can make my own UIControl subclass -with a property of type NSMutableDictionary-, as superclass of all programmatically created UIElement s in anyway, so that I can reduce the number of subclasses.
Here like this
#interface UIControl : MyControls
{
}
#property(nonatomic,retain) NSMutableDictionary *details;
#end
and make MyControls as superclass of all programmatically created UIElements
You can do this, not by subclassing, but by adding your own properties and methods to UIControl itself (the superclass of UIButton, UILabel, etc.). These will then be inherited by any standard buttons, labels, etc. that you instantiate. Objective-C lets you add your own methods very easily using Categories. However, you can't add instance variables via categories. To do that, you need to use Associative References which are documented in the Objective-C Runtime Reference.
There's a good tutorial on how to do this here.
By the way, I don't necessarily disagree with inturbidus. But if you're sure you want to go this route, that's how you'd do it.

Reusing data entry methods across views

I have written code for scrolling my table view even when keyboard hides it from entering data, using the notification center and the keyboardDidShow and keyboardDidHide methods.
The problem is that I have almost 8 views in my app where I need to enter some data.
Should I write the whole code in every single .m file, or is there any other easy way I could do it?
You could write some kind of BaseTableViewController which handles all the keyboard notifications.
Then let all the other TableViewControllers inherit from this base controller.
Either you define that method in your application delegate file or create a separate class file which contains the method and you can call it whenever it required.
myMethod.h file
#interface myMethod : NSObject
{
}
- (void) callMyMethod;
myMethod.m file
- (void) callMyMethod
{
// your code
}
In your view, call this method....
myMethod *objMyMethod = [[myMethod alloc] init];
[objMyMethod callMyMethod];
The DRY (Don't Repeat Yourself) principal would lead to creating one set of code to handle the input, not many copies that do the same thing.
The principal of decoupling would lead to a separate class for the code.
A separate class would also allow easier Unit Test to be written.
This sounds like a perfect use-case for a category.

Resources