Conceptional: two controller using the same calculation method - delegate? - ios

I have two or even more view controllers (A and B) which uses the same calculation method. I would guess the best way is to put the calculation method in its own class (lets call it C), define a protocol and thats it. If this is right, how do I know how to address the delegate?
If I alloc/init an object of the class C (the one with the calculatormethod) e.g. in class B I have the object pointer in class B - thats ok. But how do I get the object pointer known in class A or even other classes (i.e. how do I tell those controllers which want to use the delegate (i.e the same calculation method), how to address the delegate once it is alloc/init by class B?
Any help is very much appreciated!

I have two or even more view controllers (A and B) which uses the same calculation method.
Unless this is for calculating view layouts, it probably indicates you've have an MVC violation. View Controllers typically should not calculate anything. Their job is to manage user interaction. Data and calculations belong in the model.
If it is a proper view controller calculation (like managing layout), then you're correct that you want a delegate. "Delegation" is what Cocoa tends to call the Strategy pattern. You move your algorithm into another object and that lets you vary the algorithm without varying the rest of the code.
So in one case you need access to some model object, and in the other you need access to some delegate. In either case, the solutions can be similar. I'll call either situation "C" as you have.
One solution, particularly is you're using a storyboard, is to create "C" in the storyboard and wire it with an IBOutlet. You can create any object you like in a storyboard. Just drag out an "Object" and set its class to the appropriate class. Wire it up just like anything else. (This is a technique that is commonly used for multi-view nib files on OS X, and I had remembered translating over to Storyboards, but it doesn't work for sharing objects across scenes, only within scenes; so it's not as useful on iOS.)
Another solution, particularly for the model, is to implement it as a singleton, or to have a separate singleton (a "model controller") that returns it. You should not use the app delegate for this; use a singleton made expressly for this purpose.
You can create "C" in the application delegate and pass it into the root view controller (this is a proper use of the app delegate, because it's part of global program initialization). The view controllers can pass the object as part of their segues. This is my preferred solutions for passing model objects around.
If it really is a layout calculation delegate, this is probably part of some kind of configuration system (assuming it can change). The current configuration can be treated as a piece of the model, and all the above techniques still work.
If it really is just shared algorithms and doesn't vary, don't forget C functions. There is no rule that you must put all code into methods. Functions are ideal for stateless calculation. Categories can be used this way to, but simple functions have fewer complexities.

What you are saying is that both classes A and B have a common dependency (could be class C or simply a protocol C).
A and B don't need to know anything about how they are instantiated, they just need to know that they will be eventually provided with an instance implementing (protocol) C.
Another important thing is that you probably don't want C to be hold with a strong reference by either A or B.
I would look at which class F could have the responsibility to instantiate A and B.
The responsibility of this class (which could be described as a Factory) could also be to provide instances of A and B with a C instance.
So what I would do: Define a "factory" class that has methods to build instances of A and B.
Each of these methods would also provide with a C instance. This C instance could be a property of the factory class if you want it to be shared (or this factory class could also pick the C instances from a pool of available C instances).
UPDATE: not practical if you are using storyboards to instantiate your controllers. In this case you probably want to go with other given answer or implement your shared computational functions as methods of a singleton class C (see How to pass object between several views in storyboard, iOS Dev for example)

Use a superclass for A and B (and any number of additional controllers) that contains the calculation method. By using a superclass, you don't have to alloc init another class or use delegates, all the subclasses will have access to the method.
Another approach that would be more general would be to implement a category on UIViewController to add the calculation method. This way, any controller that descends from UIViewController (UITableViewController, UICollectionViewController, etc.) would have access to that method.
After Edit:
I see in your comments that your calculations have nothing to do with the controllers, just some sort of algorithm, so a category or subclass of UIViewController is probably not the best way to go. If you want to do it in another class, any controller that needs to use it, can instantiate an instance of that class, set itself as delegate, and get the result back through the delegate method (that is, if you even need a delegate -- if the calculation is fast, then you can just return a result from the method rather than using a delegate). After your controller gets the result back, the instance should be deallocated. You don't have to worry about which controller set the delegate, since each controller creates its own instance of the calculation class, and sets itself as delegate. I use this kind of structure for apps that need to do downloads from a server from multiple controllers. The download class is instantiated, does its work, sends back the result in a delegate method, and then gets deallocated. It only sticks around for as long as it needs to to do its work.

Related

Will adding multiple methods in shared singleton class cause any performance issue?

In a shared class I created, some methods in the shared class are called only once from a view controller . Do I need to add those method inside view controller class? Will adding those methods directly inside view controller improve performance?
I know singleton instance will be allocated once and it will retain for whole application, In that case calling method from singleton class or adding method directly inside view controller doesn't make any performance difference is what I guess!
You should keep the methods separate in a Model class (often a singleton) if these methods do not belong in the View Controller class. That way you are implementing the MVC design pattern which is good to apply to your projects for many reasons (read a good design patterns book for more).
Performance is not something you have to worry at this point (you hardly ever see any improvement by adding these methods directly to the View Controller), but code readiness and clean code practices are something that will actually pay off.
Keep also in mind that the view controller is there for mediating control between the model and the views, so anything related to this task should be in the View Controller code.
Actually the Singleton class instance initialised once per application. So ideally you should use that for sharing common data between view controllers .
Now about method implementation. If those method are doing something which is not related to view controllers for example if those methods are modifying some data and returning back to the controller and if that is common throughout all the controllers then you can implement that in Singleton class . I dont think there will be any big performance issue if you go with either method . Its just matter of clean coding .

I need to understand why delegation in Objective-C is so important, what makes it so special?

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.

Have multiple instances of a class point to one object #property

I will try to make this question as understandable as possible. I am implementing core data in my app, and I need to access the NSManagedObjectContext from around 10,000 different instances of a class (this class extends UIView). The Core Data stores what is displayed on these instances and the class builds it.
Everything that I have found so far uses View Controllers, of which you only have one instance, so you can just alloc init the VC in AppDelegate, set an #property for NSManagedObjectContext and be on your way. This does not work for my program.
What I want to do is have many instances of my CoreDataHelper class (which I will alloc init in the class that I have around 10,000 instances of, which all have a property pointing to the same NSManagedObjectContext. Is this a possible way to do it or will I have to make my program less flexible by moving all of the code to create the 10,000 different objects to the View Controller?
Sure, just put your NSManagedObjectContext in a singleton and all your instances can access the single class.
It does not matter if you get your managed object context from a singleton or from your app delegate (where presumably you the core data stack is set up by default).
To follow the pattern suggested by Apple with view controllers, do the exact same thing with your views: give them a #property of type NSManagedObjectContext and set it during initialization. Seems straight forward enough.
The advantage of the singleton is that you do not even need the property on your view but can call the singleton instead. But why go there? From your comments I understand that you do not really know how a singleton works. You don't need it. Go with the class property solution.
One more caveat: with your setup, you are seriously braking the MVC architecture by giving the views access to your data. Instead, you should indeed have a view controller do this and then populate your views with the retrieved data. I do not think that there is a compelling reason to deviate from this principle.

iOS: class instances connection and architecture with multiple UIViewControllers

I have a theoretical-practical question. I can't understand how I must do. I have a class let's call them DataManager that manage all plist writing-reading things and I need to get access to plist (i.e. work with that DataManager class) from different UIViewControllers.
I also have one class, I call it ModelManager, that is work with all kind of "utilities classes", include my DataManager. ModelManager works only with one complex UIViewController right now, let's call it MainUIViewController for clearness. And for now, I thought that all calls from UIViewControllers will be comes to ModelManager and from it to end-call classes. But now I'm confused.
Here is an illustration of my architecture:
I'm see different approaches and don't know how to decide and if there is some rules or guides for that. So, here is my choices:
1) I add some interface to ModelManager and from my another UIViewController (not a MainUIViewController) allocate and initialise it.
2) I add some interface to ModelManager and create a property with reference to ModelManager in another UIViewController and when segues performs set this property from MainUIViewController.
3) Work with DataManager itself and allocate and initialise it from another UIViewController
4) Work with DataManager itself and create a property with reference to DataManager in another UIViewController and when segues performs set this property from MainUIViewController.
Which approach is correct?
I know that this is some kind of depends from developer which approach to choose, but I never read and didn't find any tutorial or guide of how to develop multi-class architecture.
Ask me about any circumstance that you want to know.
You can use a singleton or you can instantiate one instance of the class in your app delegate and pass it around to all your view controllers via #propertys on each controller. There's no right answer, it's mostly a matter of preference. I prefer to make my ModelManager/DataManager type classes singletons, but a lot of people are rabidly opposed to singletons. However, if you work with Cocoa for any length of time you'll find that it's full of them (NSUserDefaults, NSFileManager, UIDevice, probably some others I'm forgetting).
Here's a good example on how to create singletons: http://www.galloway.me.uk/tutorials/singleton-classes/
BTW: Once you have your singleton, learn how to use KVO to make your view controllers respond to changes in the model. It's pretty fantastic once you get the hang of it. http://nshipster.com/key-value-observing/

What is the purpose of an iOS delegate?

I understand what a delegate does in iOS, and I've looked at sample code, but I'm just wondering about the advantages of this type of encapsulation (as opposed to including delegate methods in the primary object).
The advantage of the delegate design pattern is loose coupling. It enables class A (the delegate) to depend on class B (the delegating class) without class B having to have any knowledge of class A. This ensures that the dependency relationship is one-way only, rather than being circular.
It also forms the foundation (lower case "f") of Apple's frameworks because it allows them to invoke your code as appropriate when functionality specific to your application is required. For example, responding to a button tap or telling a table view how many sections there should be.
Delegation is a design pattern not only used in iOS but many other languages. It enables you to hand values and messages over in your class hierarchy.
In iOS, delegation requires the "delegate" class to implement a protocol which contain methods that the "delegating" knows about. Still following?
The delegating class's implementation will call these protocol methods, but the delegate class will implement these methods in their class.
This keeps your Classes clean.
In reality, you don't really need delegation if you can add new methods to a single class. But for UIKIT's UIView class, Apple will not allow you to add new implementations to their class.
correct me if I'm wrong.
The most common use of a delegate in iOS is to establish communication within modules that are unrelated or partially related to each other. For example, passing data forward in a UINavigationController is very easy, we can just use segue. However, sending data backwards is little tricky. In this case, we can use delegate to send the data backward.
Let's call, the class, associated with the first Controller ClassA and the class, associated with the second Controller ClassB. The first Controller is connected to the second controller with a forward segue. We can pass data from ClassA to ClassB through this segue. Now, we need to pass some data to ClassA from ClassB for which we can use delegates.
The sender class(ClassB) needs to have a protocol in its header file(.h) and also a reference of it as delegate inside the block, #interface ClassB .... #end. This reference let's the ClassB know that it has a delegate. Any class that wants to use this ClassB will have to implement all of this protocol's required methods(if any). So, the receiver class,ClassA will implement the method but the call will be made by the sender class, ClassB.
This way, receiver class doesn't need to worry about the sender class' internal structure, and can receive the required information.
Delegation as I understand it is when an object will pass the responsibility of handeling an event to another object thus "delegating" the responsibility to that object.
For example if you have an NSButton in iOs you generally assign the Delegate to be the parent view controller. This means instead of handeling touchUp events in the definition of the button it is instead handled in the view controller.
The main advantage of delegation over simply implementing methods in the "primary object" (by which I assume you mean the object doing the delegating) is that delegation takes advantage of dynamic binding. At compile time, the class of the delegate object does not need to be known. For example, you might have a class that delegates the windowDidMove: method. In this class, you'd probably see some bit of code like
if([[self delegate] respondsToSelector:#selector(windowDidMove:)]) {
[[self delegate] windowDidMove:notification];
}
Here, the delegating class is checking at runtime whether its delegate responds to the given method selector. This illustrates a powerful concept: the delegating class doesn't need to know anything about the delegate other than whether it responds to certain methods. This is a powerful form of encapsulation, and it is arguably more flexible than the superclass-subclass relationship, since the delegator and the delegate are so loosely coupled. It is also preferable to simply implementing methods in the "primary object" (delegating object), since it allows runtime alteration of the method's implementation. It's also arguable that this dynamic runtime makes code inherently more dangerous.
Delegate is an important design pattern for iOS app.All apps directly or behind the hood use this delegate pattern.
Delegate design pattern allows an object to act on behalf of another.
If we are working with tableview then there are "tableViewDelegate" and "tableViewDataSource". But what this means
Suppose you have a tableview.
now some major concern for this.
1.what is the datasource(the data that will appear in table view) for this tableview?
2.How many row for table view etc.
delegate design pattern solve these question using another object as the provider or the solver of these question.
An object mark himself to the table view and ensure the table view that "Yes i am the man who can assist you" by marking himself as the delegate to the table view .Thanks
The class marked as delegate takes the responsibilities to handle the callbacks sent while some event occurs. For example, in case of UITextField, there are some methods called when some events occurs like editing started, editing ended, character typed etc. These methods will already be defined in the protocol. We will have to assign delegate for that i.e. which class is going to handle these events.
With the help of a delegate, two-way communication can be achieved. A delegate might be used to make an object reusable, to provide a flexible way to send messages, or to implement customization.
In iOS ecosystem especially UIKit Framework which consists of UIApplication, UITableView, UICollectionView, UITextfield & so on uses delegate & datasource design pattern intensively to communicate data to and fro.
Delegate design pattern is used to pass/communicate data from FirstVC(Delegator) to SecondVC(Delegate) to complete a task.
Here, SecondVC(Delegate) conforms to a protocol delegate & implements all its requirements like methods by providing body to complete that task given by FirstVC(Delegator).
Also, FirstVC(Delegator) object will be having a optional property of protocol delegate type i.e delegate which must be assigned by SecondVC(Delegate).
Now, FirstVC(Delegator) can call that method residing in SecondVC(Delegate) by passing data from its delegate property.
EX: CEO(FirstVC) which passes data i.e "confidential data" to Secretary(SecondVC) to do further processes using that data.
Datasource design pattern is part of Delegate pattern which is used to pass/communicate data from SecondVC(Delegate) to FirstVC(Delegator) when a task is assigned to SecondVC(Delegate).
Here, SecondVC(Delegate) conforms to a protocol datasource & implements all its requirements like methods with return type by providing body to talk back to FirstVC(Delegator) after the task is given by FirstVC(Delegator).
Also, FirstVC(Delegator) object will be having an optional property of protocol dataSource type i.e dataSource which must be assigned by SecondVC(Delegate).
Now, FirstVC(Delegator) can call that method with a return type residing in SecondVC(Delegate) by passing data from its dataSource property.
EX: Secretary(SecondVC) replies back with a data i.e "Sir, I am already having too much work to do. Please, can you assign that data to others" to CEO(FirstVC). Now, CEO(FirstVC) will analyse that data to do further processes.
Delegation means one object passes behaviour to another object..

Resources