Here is the situation:
I have Controller A and controllers B, C that are subclasses of A.
Next, i have classes RLMObject and News, Events that are subclasses of RLMObject.
In A i have a property commonProperty. And it presents in B and C like superclass's property.
Question: I need something like to tell to compilator, that depend of controller this is a property of custom class. For example, in A this is id, in B this is News, in C this is Events. Because in A i do common things with this property, like getting data and setting it in this property. And in B, C, i work with UI and need a concrete class of this property.
Maybe this is not clear description, and last example (about getting data) is a custom situation, but if somebody get through it, please share your experience.
Related
In Swift, I am trying to build a simple app that runs the card game war. There are two view controllers, one for normal gameplay and one in case of a tie. So, in my code, I have two different classes, one called mainScene and one called tieScene. To store which cards the player has and which cards the enemy has, I use two arrays named playerArray and enemy Array. If a tie occurs, I segue from mainScene to tieScene. How do I incorporate the information for playerArray and enemyArray from class mainScene, and use these values in class tieScene?
One thing I tried was subclassing tieScene as part of mainScene as follows:
class tieScene: mainScene {...}
This allowed me to use the playerArray and enemyArray in class tieScene. However, the option to connect tieScene to my second view controller in Interface Builder was not there when I subclassed tieScene.
So, I have two questions:
Did I subclass tieScene wrong and is that why I couldn't connect tieScene in my interface builder?
Besides subclassing, how can I use the information from one class in another class?
This is OOP 101 stuff.
Subclassing does not share information.
Cars and trucks are both motor vehicles
Sedans and coupes are both subclasses of car. Say both have a radio with a radio station property.
If I change the radio station in my sedan instance, that does not mean you can query the radio station in your coupe and find out what station I'm listening to.
Separate objects are completely separate from each other, and have their own instance variables.
You can either set up a link between your two objects and define a protocol to communicate between them, or if you want to save global app state information then maybe you need a data container singleton. See this thread I created for a discussion of the different options:
How do you share data between view controllers and other objects in Swift?
I don't think you're understanding what a subclass is.. If you're subclassing, then that just means that the child class has the same properties as the super class, so it will have the arrays but they are not persisted.
There are a couple of things you can use, the easiest would be to simply create the arrays in your tie view, then when you create a new tie view, set the arrays. Or create a method to setup the tie view with the arrays(initWithEnemyArray.....)
You should not be using subclassing like this, subclassing is not used to share information, that is a misuse of what object orientation is about. It would not work because when your program runs you will have a separate instance of type tieScene and another instance of mainScene. Therefore you will have two separate instances of the data, not one instance which is shared. You should consider making a model class and storing your data there. Read about MVC.
Regarding OOP and inheritance, make sure you understand the difference between a class and an instance of a class. You are mixed up thinking an instance and a class are the same thing, they are not.
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.
B is subclass of A. C is a subclass of A. When i create c i do if((self = [NSKeyedUnarchiver unarchiveObjectWithFile:…])) { } inside the .m in C.
So despite i set the the superclass in C.h to be B (which is what i want), when i create the C object from unarchiveObjectWithFile: since this object is subclass of A, i can’t force it to be subclass of B. (Hard to explain sorry).
Is there any workaround ???
In other words: when i unarchiveObjectWithFile:… an object that pertains to a class A, and i have another class B that is subclass of A, can the unarchiveObjectWithFile: be a subclass of B? (wich is allowed since B is subclass of a)
If I understand correctly: No.
If you archive an instance of B then when you unarchive it you get an instance of B, likewise for instances of A and C.
However, in non-technical language, a subclass is everything its superclass is plus some extra bits. You can't[*] take an instance of a superclass, created directly or from unarchiving, and make it into an instance of one of its subclasses - the "extra bits" are not there.
HTH
[*] Before someone comments: Yes, this is not absolutely true in all situations, but you are entering obscure, highly specialised, and dangerous waters. Don't go there.
Addendum
Seems you might be in the category where changing the class of an object is safe: you should be able to change the class of an instance to a subclass provided the subclass adds no instance variables or properties. To do this you can use the Objective-C runtime functions:
id obj = ... some instance of class A
object_setClass(obj, [B class]); // where B is a subclass of A which adds no properties or variables
You can also use the unarchiving classes to set the class.
Do not do this casually. Consider alternatives, but sometimes it is an appropriate solution.
The unarchiver wants to create the same type of class that was perviously archived, and that's generally what you want too.
You could look at using setClass:forClassName: to change the class that will be unarchived, but you stand a good chance of ruining everything sooner or later...
Based on the particle comment:
Another option is to take the superclass instance and 'wrap' it in your subclass instance. So, you can archive and unarchive your subclass instance and it will contain the superclass instance. Any method that your subclass doesn't directly respond to you can forward on to the superclass instance.
In this way you have 2 objects but you aren't tampering with anything or relying on implementation details of classes that you don't own.
In my app I have a storyboard with two scenes. The first one is a Summary-View-Controller and just shows some data. But you can tap on it and switch to a Edit-View-Controller scene where you can make changes. To report the changes back to the Summary-View-Controller the Edit-View-Controller will get a reference to his parent. When editing is done he will call a method in his Parent-View-Controller.
The property in the Edit-View-Controller looks like that:
#property (weak, nonatomic) id <NameEditViewChangedProtocol> parentController;
My app works fine. That is not my problem. But in many tutorials I read a property like this is just called delegate.
#property (weak, nonatomic) id <NameEditViewChangedProtocol> delegate;
I know what delegation is and how it works but for me parentController is a more meaningful name. delegate, that could just be anything. So my question is: When should I call a property like this delegate? Are there any rule how to use this name?
I know what delegation is and how it works but for me parentController
is a more meaningful name. delegate, that could just be anything.
I think you've answered your own question here. A delegate is a helper object that "could just be anything" as far as the delegating class is concerned. The name parentController assumes something specific about the relationship between the two objects. If you know that that relationship will always exist, then it's appropriate to use that name. On the other hand, if the two objects only happen to have that relationship, but the relationship isn't important to the fact that one object is using the other as a helper, then use delegate (or something similar).
So, is it necessary that the objects in question have a parent/child relationship? Are you sending messages to parentViewController specifically because it's the parent? Or is it conceivable that some other object could respond to the same messages?
Usually names of properties of type id<some protocol> are the same as the last part of the protocol name, e.g. the 'delegate' property of a UITableView is a property of type id<UITableViewDelegate>, and the 'dataSource' property is of type id<UITableViewDataSource>. If you name your protocols by their purpose, the name of a property of type id<some protocol> should come naturally from the protocol name. For what it's worth, protocol names don't usually include the word 'Protocol'.
Andrew's answer about how to name the property could help you make a better name for the protocol as well, if you follow the protocol/property name correspondence which I explained.
Edit: Fix formatting throwing away <protocol names>
Call it a delegate when it will be used to make decisions at runtime about how the edit view controller should behave, or is to be notified of events, incoming data, etc. Call it delegate if the edit view controller is to be reused in multiple contexts, and the delegate's class can be anything (possibly conforming to a delegate protocol).
It may make sense to call it parentController if you know that the relationship between the two is always going to be a parent-child relationship with the parent 'owning' the child, rather than the more abstract delegate relationship.
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..