So I've read about delegate explanation and practices a lot, but I still seem to not get it, I have specific questions and I would love to have some insightful simple answers.
Why use delegate over instance method? In UIAlertView why not just make – alertView:clickedButtonAtIndex: an instance method that will be called on my UIAlertView instance?
What is the delegate property? why do I have to make delegate property and define it with that weird syntax #property (nonatomic, strong) id <ClassesDelegate> delegate
Is delegate and protocol are two faces for a coin?
When do I know I should implement delegate in my app instead of direct calling?
Is delegate used as much and as important in Swift?
What gets called first and why? The method in the class who made himself a delegate? or the delegate method itself in class where it is declared?
Thank you for taking the time to go through this, I am desperately looking for a clear and helpful answers to my questions, feel free to give example or cover some related topic!
The advantage of delegation is Dependency Inversion.
Usually code has a compile-time dependency in the same direction of the run-time calling dependency. If this was the case the UITableview class would have a compile-time dependence on our code since it calls our code. By using delegation this is inverted, our code has a compile-time dependency on the UITableview class but the UITableview class calls our code at run-time.
There is a cost involved: we need to set the delegate and UITableview has to check at run-time that the delegate method is implemented.
Note: When I say UITableview I am including UITableviewDelegate and UITableviewDatasource.
See: Dependency inversion principle and Clean Code, Episode 13.
Maybe a real life example can better describe what's different in the delegation design pattern.
Suppose you open a new business, and you have an accountant to take care of the bureaucratic stuffs.
Scenario #1
You go to his office, and give him the information he needs:
the company name
the company # number/id
the number of employees
the email address
the street address
etc.
Then the accountant will store the data somewhere, and will probably tell you "don't forget to call me if there's any change".
Tomorrow you hire a new employee, but forget to notify your accountant. He will still use the original outdated data you provided him.
Scenario #2
Using the delegation pattern, you go to your accountant, and you provide him your phone number (the delegate), and nothing else.
Later, he'll call you, asking: what's the business name?
Later, he'll call you, asking: how many employees do you have?
Later, he'll call you, asking: what's your company address?
The day after you hire a new employee.
2 days later, he'll call you asking: how many employee do you have?
In the delegation model (scenario #2), you see that your accountant will always have on demand up-to-date data, because he will call you every time he needs data. That's what "don't call me, I'll call you" means when talking of inversion of control (from the accountant perspective).
Transposing that in development, for example to populate a table you have 2 options:
instantiate a table control, pass all the data (list of items to display), then ask the table to render itself
instantiate a table control, give it a pointer to a delegate, and let it call the delegate when it needs to know:
the number of rows in the table
the data to display on row no. n
the height the row no. n should have
etc.
but also when:
the row no. n has been tapped
the header has been tapped
etc.
Firstly, don't feel bad that all if stuff isn't clear yet. This is a good example of something that seems tricky at first, but just takes time really click. That will happen before you know it :-). I'll try and answer each of your points above:
1) Think of it this way - the way UIAlertView works now, it allows Apple to “delegate” the implementation of the alertView:clickedButtonAtIndex: to you. If this was an instance method of UIAlertView, it would be the same implementation for everyone. To customize the implementation would then require subclassing - an often over relied upon design pattern. Apple tends to go with composition over inheritance in their frameworks and this is an example of that. You can read more on that concept here: http://en.wikipedia.org/wiki/Composition_over_inheritance
2) The delegate property is a reference to the object which implements the delegation methods and whichs should be used to “delegate” those tasks to. The weird syntax just means this - a property that holds a reference to an object that adheres to the protocol.
3) Not quite - delegation leverages protocols as a means for it’s implementation. In the example above, the is this the name of a protocol that an object which can be considered a delegate for that class must adhere to. It is inside that protocol that the methods for which a delegate of that class must implement are defined. You can also have optional protocol methods but that’s a different topic.
4) If I understand the question correctly, I think a good sign that you may want a delegate to be implemented instead of simply adding instance methods to your object is when you think that you may want the implementation of those methods to be easily swapped out or changed. When the implementation of those methods changes considerably based on where/how the functionality your building is being used
5) Absolutely! Objective-C and Swift are programming languages and the delegation pattern is an example of a design pattern. In general design patterns are hoziontal concepts that transcend across the verticals of programming languages.
6) I’m not sure I understand you exactly but I think there’s a bit of misunderstanding in the question - the method does not get called twice. The method declared in the delegate protocol is called once - typically from the class that contains the delegate property. The class calls the delegates implementation of that property via something like:
[self.delegate someMethodThatMyDelegateImplemented];
I hope some of this helped!
Sometimes you want your UIAlertView to work different in different contexts. If you set your custom UIAlertView to be delegate of itself it has to provide all those contexts (a lot of if/else statements). You can also set seperate delegate for each context.
This way you say to your compiler that every class (id) which implements protocol ClassesDelegate can be set to this property. As a side note it should usually be weak instead of strong to not introduce reference cycle (class A holds B, and B holds A)
Protocol (interface in other languages) is used to define set of methods which should be implemented by class. If class conforms to the protocol you can call this methods without knowledge of the specific class. Delegate is pattern in which class A delegates some work to class B (e.g. abstract printer delegates his work real printer)
When you need few different behaviours which depends on context (e.g. ContactsViewController needs to refresh his list when download is finished, but SingleContactViewController needs to reload image, labels etc.)
It is one of the most fundamental patterns in programming, so yes.
It's the same method
You can't just add a method to UIAlertView, because you don't have the source code. You'd have to subclass UIAlertView. But since you have more than one use of UIAlertView, You'd need several subclasses. That's very inconvenient.
Now let's say you use a library that subclasses UIAlertView, giving more functionality. That's trouble, because now you need to subclass this subclass instead of UIAlertView.
Now let's say that library uses different subclasses of UIAlertview, depending on whether you run on iOS 7 or 8, and UIAlertview unchanged on iOS 6. You're in trouble. Your subclassing pattern breaks down.
Instead, you create a delegate doing all the things specific to one UIAlertview. That delegate will work with the library just fine. Instead of subclassing a huge and complicated class, you write a very simple class. Most likely the code using the UIAlertview knows exactly what the delegate should be doing, so you can keep that code together.
My idea is to create a category of UIActionSheet in order to be able to mock the different possible user interactions (select item / cancel) and to check the correct initialization.
I was hoping that by importing the category that I created into my test, all farther usages of UIActionSheet are going to be through that category, but it's not the case. Has anyone had similar experience? What other ways do you suggest to do UI mocking?
#interface UIActionSheet (LMActionSheetMonkey)
bla bla
#end
Another idea is to import the category in the class using #ifdef TESTAPP, but i'm trying to affect my actual implementation for the sake of testing.
You can certainly do this, especially if you combine it with a bit of swizzling. I have recently done this.
EDIT - the below bit is no longer true.
I used to use OCMock, but it doesn't work properly with ARC and weak references:
http://joris.kluivers.nl/blog/2012/03/26/weak-references-to-nsproxy-with-arc/
because of an iOS bug whereby a weak reference to an NSProxy is always nil
Why is my object's weak delegate property nil in my unit tests?
I have checked recent header files for PSListController , PSViewController and PSBaseView, but there is no method for acknowledgement of view creation, like iOS has viewDidLoad - Although there are many methods available for view Display. One I found is: -(id)initForContentSize:(CGSize)contentSize, but I don't want to use it as I don't think it would be appropriate to do so.
So which method should I choose in order to initialize my instance variables or do other stuff? Thanks.
Note: I am using rpetrich's Header Files.
Some of those headers are slightly older on the repository but looking at an iOS 7 version of PSViewController you will see that it is a subclass of UIViewController. UIViewController does contain viewDidLoad so PSListViewController "should" contain the same.
Source: http://www.developer.limneos.net/?framework=Preferences.framework&header=PSViewController.h
I have been stumped on this for awhile. I have asked multiple developers I know and they think I have forgotten to "#import the .h file". But I know I have, I have tested the class in more than one file in my project. It only works in the "VNDecalLevelListViewController.h" ( which I will post its implementation if a picture). When I try and call my "initForNewDecal" method for my "VNDecalCreatorViewController.h" class in my "VNAdminViewController.h" class I received the error that this method has not been declared in "VNDecalCreatorViewController.h". But when I call it in my "VNDecalLevelListViewController.h" class it works.
I am able to allocate and use "init" to create the object and it loads with a work around I made. But I am new to programming and I can tell there is definitely a better solution.
As you will soon see as i got to allocate the VNDecalCreatorViewController in the " VNAdminViewController" the option to initialize VNDecalCreatorViewController with the proper initializer "initForNewDecal" isn't even a option.
Anyone know why this is happening ? I want to write the code right I am trying to figure out why my header file is only being read in one class.
I guess this is because you mutually imported between the two class Creator and Level. I mean you may have #include "VNDecalCreatorViewController.h" in VNDecalLevelListViewController.h and vice versa. The solution is to use #class to forward declare any classes you may need to reference instead of #import'ing the header.
Make sure that the method is declared in the header file and implemented in the .m file.
I have class called ViewController. How to make this class is a sub-class of "metaiosdkViewController" and "JWslideViewController". Help me with syntax.
i have written like this
#interface ViewController : MetaioSDKViewController,JWslideViewController
but this giving me error
objective-c doesn't support multiple inheritance,but if you want to add some extra behaviour you can achieve it through delegates..
yes objective-c doesnt support multiple inheritance but you can give one parent so
#interface ViewController : MetaioSDKViewController
and
#interface MetaioSDKViewController : JWslideViewController
this is just an idea I know you can implement well as per your need
What is it that you want to achieve with multiple inheritance?
Do you want to override methods from each of these super classes?
Note that objective c provides 2 mechanisms for extensibility:
1) Implementing a Protocol and make your object the delegate:
#interface ViewController : <MetaioSDKViewController,JWslideViewController>
This enforces ViewController to implement certain methods as defined in contract by 2 delegates, and at some point in processing, they get called. If you don't implement them, they may simply not be called but you may not get desired functionality.
Example: UITableViewDataSource protocol that defines many methods that UITableViewController subclass implements. cellForRowAtindexPath is very famous example of a delegate method that your own table view subclass must implement to draw your own custom cells.
Note that this is not the type of extensibility that subclasses provide in general sense. Your class does not extend any functionality here. Rather it becomes what it says - a delegate - someone who is assigned to do some task. Like you do:
yourTableView.delegate = self; //tell self to be the delegate of yourTableview
Library code does it's stuff and in some point in processing it calls [delegate someMethod]. If your own class implements it, it calls it, otherwise delegate will be nil, and it may just be NO-OP and you don't get desired functionality. Again, this is implementation-dependent. Maybe the protocol defines that the method is compulsory, in which case your class MUST implement this method in order to compile.
2) Implement a category:
This is sort of a shortcut way to extend library classes. They act like an extra stub which, when your code runs, attaches itself to the already existing memory layout of the library objects and provides extra functionality.
You can define a category on any of the in-built classes as well. In fact that is the primary objective it is used for. For example, here is an NSString category which provides HTML conversion. There are hundreds of categories implemented as open source and they provide enormous benefits where library code falls short. Discussing their suitability in entirety is however out of scope for this discussion.
One thing to note however is: You do not override anything using a category. Rather you are supplying something in extra. For example if you want some custom drawing across all your app views, you can define a category on UIView in your project and then all your views could simply include the category header file. You don't even have to inherit from this category, you simply inherit from the base type.
e.g. in the NSString category example above, you do not have to define your NSString to be of type NSString+HTML. Instead you just include the responsible NSString+HTML.h file wherever you want those extra methods like stringByConvertingHTMLToPlainText and so on. The changes remain limited to your project - to the files where you include this category.
Categories do not provide for extra data members - and that is something that only inheritance can provide. Yet, multiple inheritance among viewcontrollers is something you should definitely reconsider hundred times - you will see that what you are looking for is not multiple inheritance.