Quick question about semantics :)
If I was writing a protocol, which is preferred:
// (a)
#protocol MyProtocol
#property (nonatomic, copy) NSSet *things;
#end
vs.
// (b)
#protocol MyProtocol
- (NSSet *)things;
- (void)setThings:(NSSet *)things;
#end
(a) is cleaner code but has the implication that implementing classes will have an ivar for things, which isn't the case in my project. Because of my use case, things cannot be KVO either. It also implies that the implementing class will copy things, which it's not doing in every case for me.
(b) is more accurate code (it's very explicit about what you can / can't do i.e. no KVO) but it's a little messier.
Any opinions?
I am amending my answer that (a) probably is not best for a protocol but best for a non-protocol interface.
I would go with the #property. How a property is implemented is an implementation detail and I never consider that from the outside.
Consider a v1 implementation where the property is only that. In v2 the internals are changed and either the setter or getter is made a method. Totally reasonable, one of the reasons that properties are good, they allow such changes, they hide the implementation details.
Also consider the opposite, in the next version where is is desired to remove the methods and replace them with a property. Again an implementation detail that a property in the first instance covers quite well.
Finally, in this case there is a copy attribute which provided explicit information of how a call with a mutable object will be handled, that is lost in the method implementation.
Protocols define messaging contracts [1]. They are not intended to store data. According to the Apple documentation you are only supposed to add properties to class extensions (you can add properties to categories but the compiler won't synthesize an ivar) [2]. Depending on what you are trying to do I would use one of the two following approaches to be consistent with the documented usage of the Objective-C language:
If you have the source code of the class (its one you created) then use a class extension.
If you do not have the source code sub-class the object.
That being said, if you really need to do it the other way use option (b). It is more corect and more correct is cleaner code!
Here is another question that deals with the same issue.
Good luck
I think case 'a' makes misinformation: class adopting protocol MyProtocol can follow not rules nonatomic and copy.
And for me it's very odd add properties inside protocols. It is going against paradigms of object oriented programming: delegates shold do some action, not provide informations.
So I advice you not use 'a' and 'b' cases, but to think again about yours programm architecture.
Related
I have below classes
#interface Document : NSObject
//Root document
#end
#interface ExtendedDocument1 : Document
//sublcass of document, with specific behaviour
#end
#interface ExtendedDocument2 : Document
//sublcass of document, with specific behaviour
#end
#interface EncryptedDocument : Document
//Supports encryption of document
#end
If I want to encrypt the ExtendedDocument(1/2), how can I achived this? If I subclass the ExtendedDocument with EncryptedDocument, the extended document will become encrypted by default.
How to solve this design issue? which pattern I can use to solve this kind of problems. Looks like I am missing something.
You could receive an intermediary interface reference in the EncryptedDocument initializer. To do so, you must find out which is the minimally sufficient interface between all your class interfaces needed to expose information for documents to be encrypted. It may so happen that Document does the job. If not, you should create this interface and extend all others from it, or create a protocol, and make your classes implement it. Then, just add a specialized initializer for EncryptedDocument:
#interface EncryptedDocument
- (id)initWith:(Document*)document;
// whatever else an encrypted document has to expose in its interface ...
#end
This has the advantage of keeping the original plain document untouched, and if you don't need it anymore you can release it for garbage collection.
But in this case you might want to separate the responsibility of actually implementing the encryption, which is the job of an algorithm implementation, from the EncryptedDocument representation, which is more tied to the data model of such a document. One way to achieve that is to employ the Strategy Design pattern and remove the encryption work from the EncryptedDocument. Perhaps you could remove the EncryptedDocument altogether from the hierarchy, changing the return value for the encrypt method bellow. But this depends more on your data model and application domain. (https://en.wikipedia.org/wiki/Strategy_pattern).
#interface DocumentCypher
- (id)initWithMethod:(id<CypherMethod>)method;
- (EncryptedDocument*)encrypt:(Document*)plainText;
#end;
But this depends on the complexity of the problem you are trying to tackle, the more "naive" and simple solution could be easily refactored when the need for introducing more complex behavior arises.
What you are missing is that inheritance is not the swiss army knife of programming. In that specific case, a protocol such as Encryptable can help support an interface implementation and call an instance of an object by referring to the protocol type. Check the following link:
Working with Protocols
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.
For the purposes of my project's UI, I am creating a general method in a category on UIViewController that sets up the UI for a navigation item. This particular navigation item has a yellow button corresponding to an action (save, ok, choose etc.) and a gray button (cancel, close)
- (void)configureAsSaveCancelIPadHeaderWithTarget:(id)theTarget actionForYellowButton:(SEL)selYellow actionForGrayButton:(SEL)selGray
I think I can make this method smaller like so:
- (void)configureAsSaveCancelIPadHeaderWithTarget:(id<PSaveCancelViewControllerNavigationBar>)theTarget
and have the target respond to a protocol.
The protocol would look like this:
#protocol PSaveCancelViewControllerNavigationBar <NSObject>
#required
- (void)save:(id)sender;
- (void)closeThisView:(id)sender;
#end
The #required keyword will only give a warning if those 2 methods are not implemented.
Question
Is it considered a good pattern to assert in the configureAsSaveCancelIPadHeaderWithTarget: method if the target contains those two methods? Like so:
- (void)configureAsSaveCancelIPadHeaderWithTarget:(id<PSaveCancelViewControllerNavigationBar>)theTarget
{
NSAssert([theTarget respondsToSelector:#selector(save:)], #"The provided target must implement the PSaveCancelViewControllerNavigationBar protocol and have the methods defined in that protocol.");
NSAssert([theTarget respondsToSelector:#selector(closeThisView:)], #"The provided target must implement the PSaveCancelViewControllerNavigationBar protocol and have the methods defined in that protocol.");
I will definitely call those two methods later (save, closeThisView) and so I must make sure that the class that calls this method has them implemented.
It all depends on how 'safe' you want to make things. Just because your parameter specifies that a protocol is required doesn't actually mean that the passed instance implements that protocol. All the compiler requires is for you to promise that it does when calling (a cast).
Generally, if you're writing all of the code then it is relatively 'safe' to just use the protocol and not check at runtime.
If other people are using the code, and in particular if you are releasing the code as a library or something like that then checking becomes much more prudent as you can't make any assumptions about what other people are going to do. In this case it is much better to fail early.
No, it’s pointless and extra-wordy. You’ve declared in -configureAsSaveCancelIPadHeaderWithTarget: that you are only accepting an object that implements your protocol, so you are going to REALLY TRY HARD to bone yourself, it’s going to work.
You could be infinitely “safe” about checking if every object STILL responds to messages they say they respond to, but all the extra wordiness just makes your code hard to read, hard to change, slower, and gives you more chances to introduce bugs.
Less code is better code.
I have read a few questions on the differences between iVars and Properties like these: Why would you use an ivar?
ios interface iVar vs Property
What I would like to know is... If I am creating a BOOL that needs to be accessed in multiple methods in a UIViewController (for example) what is the best way to create these?
At present I create proprties. This works fine and as expected. But as I read/learn more it appears that creating an iVar would be better for performance.
Like:
#interface ViewController : UIViewController{
BOOL myBool;
}
Would this be better for performance, and can multiple methods access this iVar if I set the value to YES in one, can I check the value in the other - as I can with property approach?
can multiple methods access this iVar if I set the value to YES in one, can I check the value in the other
Of course you can, even if you set the value to NO. It is an instance variable and thus shared between all methods of one instance.
Would this be better for performance
No, unless you access the property very, very often, like 2^20 times per frame. Have a look at this Big Nerd Ranch post about iVar vs property performance. Usually the performance gain is not worth the loss in clarity.
The "better performance" is something that would be very rare to affect an app. Write code for clarity, then if there are performance issues profile and fix the code that is actually causing the problem.
For your purpose an ivar would be equivalent to using a property. Performance-wise the ivar is slightly better because you access it directly, whereas with a property you invoke a method (getter or setter) that was generated by the compiler in the background.
I wouldn't worry about performance, though. Typically the difference will be negligible. Unless you have some really special need, I would always use properties because it usually results in clearer code. It's also a good habit to have getter and setter methods - even if they are generated by the compiler for you - because they encapsulate the data of your class.
I usually go with this:
#interface MyVC : UIViewController
#property (nonatomic, getter=isDoingSomething) BOOL doingSomething;
#end
I also explicitly name the getter in the property declaration which gives you access to the property in a way that is easy to read. (Setting the property is done by sending setDoingSomething: and the getter is [theVC isDoingSomething])
Nonatomic properties are recommended on iOS. In regards to what I had backwards before, the default atomic behavior adds locks to the synthesized code, and is not recommended for performance reasons. Any issues with threads would have to be handled in your own setters (which you would have to do anyway when using an ivar). Personally I haven't ran into any issues with this.
I won't repeat other answers about performance but besides pointing out the fact that tapping a button sends way more messages than accessing a property, so the performance penalty is trivial.
I have a an iPhone app in which class A is a subclass of UIViewController:
Now I'm creating a new app, in which I want to re-use A, but have it subclass from B, which is fine, because B subclasses from UIViewController:
But now I have another class, C, which is a subclass of GLKViewController:
The problem comes when I try to make a third app which re-uses B without any changes. Since B inherits from UIViewController, I need to somehow tell C that it should inherit from B and from GLKViewController, which I believe is a case of multiple inheritance:
From what I'm reading, the best way to handle this is with composition, but I don't understand how to best apply it to my situation.
As a stand-in solution, I realized I could just create a wrapper class D which I can then modify on an app-by-app basis to subclass from the appropriate superclass for the task at hand:
But that seems kind of hacky. Is there a better way to do this?
Objective C only supports single inheritance. In this case you'd probably want to use protocols for common functionality. You can use a helper object to implement the protocol methods. In this case, you're not interested in whether your object is a member of a particular class, but whether it implements a specific set of methods.
you can't do that in Objective-C is single inheritance -- like java or most of the other modern languages.
use a paradigm of composition or delegation
You could possibly get that covered by using a category. It certainly is not the same as multiple inheritance but sometimes does the job.
Let me draft an example for a category and see if that does what you aim for.
Header: UIViewController+MyAwesomeExtension.h
#interface UIViewController (MyAwesomeExtension)
- (void)doSomething;
#end
Implementation: UIViewController+MyAwesomeExtension.m
#implementation UIViewController (MyAwesomeExtension)
- (void)doSomething
{
NSLog(#"doing something totally awesome");
}
#end
Now you are using it from within one of your UIViewController subclasses which also includes like e.g. GLKViewController ...
Implementation:
#import "UIViewController+MyAwesomeExtension.h"
...
[self.viewControllerDerivedClass doSomething];
...
Note that such category does have its limits. To find out more, how about researching the subject a bit further.
Overall, I think the "most" correct answer would be using protocols to get as close to multiple inheritance as possible, as Mike C. drafted in his answer. My answer is mostly a workaround for simple cases.