I frequently find myself writing "utility" classes that can be re-used throughout my projects.
For example, suppose I have an "Address Book" view. I might want to use my address book to select who gets sent an email, or maybe who gets added to a meeting request.
I'd develop this view controller so it can be used by both the email controller, and the meetings controller, with some sort of callback mechanism to let the caller know the user either finished selecting someone from the address book, or they canceled.
It seems there are basically four (reasonable) approaches one might take in this scenario;
Create an "AddressBookDelegate" protocol and a corresponding delegate property on the AddressBookController. Then use the messages defined in the protocol to communicate the result (similar to UIActionSheetDelegate).
Create an "informal" "AddressBookDelegate" protocol and a corresponding delegate property on the AddressBookController, but the type of the delegate property will be "id", and will check at runtime with "respondsToSelector:" to see if the delegate implements the methods we require (seems like most of the framework stuff has started going this way).
Pass the AddressBookController an id that represents a delegate, as well as two SELs which specify the methods to call when the user selects a user or cancels the request. The benefit I see with this is; suppose one controller supports BOTH sending emails AND setting up meetings (I know in this example that seems like bad design... but one can imagine a more generic situation where this would seem perfectly reasonable for a utility class) - In this case you could pass the AddressBookController different SELs depending on whether you're adding users to an email, or adding users to a meeting... a huge improvement over an iVar to indicate the controller's "state".
Pass the AddressBookController two blocks; one to run when the user selects someone from the address book, and one to run if the user cancels the request.
The blocks have been so tremendously useful to me, and SO much more elegant, I'm finding myself almost confused over when to NOT use them.
I'm hoping more experienced members of the StackOverflow community than I can help out with their thoughts on this topic.
The 'traditional' way to do this is with a protocol. Informal ones were used before #protocol was added to the language, but that was before my time and for at least the last few years informal protocols have been discouraged, especially given the #optional specifier. As for a 'delegate' which passes two SELs, this just seems more ugly than declaring a formal protocol, and generally doesn't seem right to me. Blocks are very new (esp. on iOS), as these things go, and while we have yet to see the tremendous volume of documentation/blogs on the best tried and true style, I like the idea, and this seems to be one of the things blocks are best for: neat new control flow structures.
Basically what I'm trying to say is that each of these methods vary in age, with none being better than the last except for style, which obviously counts for an awful lot, and is ultimately why each of these things was created. Basically, go with the newest thing you feel comfortable with, which should be either blocks or a formal protocol, and that your confusion is most likely coming from reading conflicting sources because they were written at different times, but with time in perspective, it is clear to see which supersedes the others.
[Controller askForSelection:^(id selection){
//blah blah blah
} canceled:^{
//blah blah blah
}];
is probably a hell of a lot more concise than defining two extra methods, and a protocol for them (formally or otherwise) or passing the SELs and storing them in ivars, etc.
I would just go with your first approach. It's a tried and true pattern in Cocoa, and seems to fit very well into what you're doing.
A few comments on the other approaches:
Informal protocol - I don't really see any advantage of doing this over a formal protocol. Every since formal protocols gained #optional methods, the utility of informal protocols is much less.
Passing SELs - I don't think this is an established pattern in Cocoa. I personally wouldn't consider it as better than the delegate approach, but if it fits your thinking better, then go for it. You're not really getting rid of state; you're just transforming into something else. Personally, I'd prefer to have an ivar that I can set and check without having to use selector types.
Passing blocks - This is sort of a new-age approach, and it has some merit. I think you need to be careful though because, in my opinion, it doesn't scale really well. For example, if NSTableView's delegate and data source methods were all blocks, I would personally find that somewhat annoying. Imagine if you wanted to set 10 different blocks, your -awakeFromNib (or whatever) method would be pretty big. Individual methods seem more appropriate in this case. However, if you're sure that you're never going to go beyond, say, two methods, then the block approach seems more reasonable.
Related
I often get confused with when to use DataSource Pattern and when to use the Properties for providing configuration information to objects.
I have two ways to do this,
Generally I keep a lot of properties in the Object's class that has to be configured and a method that resets the object and continues with the new properties.
And the for the Object which is configuring the other object, I keep a method that with the name configureXYZ:WithValues: , which resets the properties and calls the reset method of the object to be configured.
This I have seen with MPMoviePlayerController, that we have to set properties.
and Other way is how tableView works, all the configuration information comes from datasource methods.
Can anyone throw more light on which way is preferred in which scenario.
Because Its often I feel tempted to use design patterns and make the code look stylish but I wanted to know when do we actually need these.
I am absolutely clear with delegate pattern and have to use it on regular basis.
DataSource was one thing I was never clear with.
When designing a class, the key factor you should consider when deciding between using a delegate or properties is how often the values can change. Properties work best if you will set the values one time and they should never change again. Delegates (of which datasource is just an example) work best if the values might change over time or change due to conditions.
For example, in UITableView, the number of rows is highly dynamic. It could change for many reasons outside of the control of the table view. What the rows even represent is highly dynamic. They might be data; they might be menu options; they might be pieces in a game. UITableView doesn't try to guess or control any of that. It moves it to a delegate (datasource) where potentially very complex decisions could be made.
MPMoviePlayerController has a few controls that mean very specific things and should almost never change (particularly once the movie starts playing). Basically you set the thing up, hit play and walk away. In that case, a delegate would likely be overkill.
There are many cases that are in the middle, and either way may be ok. I would encourage developers to consider delegation first, and then if it doesn't make sense go with properties. This isn't because delegation is always the right answer, but more because most C++- or Java-educated developers don't think in terms of delegation, so should make a conscious effort to do so.
Some other thoughts along these lines:
When using properties, it is ideal if they are configured at initialization time and are thereafter immutable. This solves a great number of problems.
If you find yourself needing a lot of properties, delegation is probably better and often simpler.
Delegate notification methods (somethingDidHappen:) are often better implemented as blocks. (Blocks are relatively new in ObjC. Many delegate-based Apple interfaces are moving to blocks, but you'll see a real mix out there for historical reasons.)
The difference between "delegate" and "datasource" is that a delegate manages behavior, while a datasource provides data. They are typically implemented identically.
It mostly depends on the dynamics of the class. UITableView is a very dynamic interface element. Its data comes and go. You can add/remove/edit/sort. You can interact with it. IF you assign properties to a tableView, it loses some of the properties that makes it as robust as it is. MPMoviePlayerController, on the other hand, has a different purpose. I have never used this class but by the looks of it, it reads one video file and provides playback. There is not many changes to it, so properties makes a lot of sense.
If you are writing a class, and you need that class to be as flexible as possible(UIPickerView, UITableView), having delegates allows you to do so. If your class only works with limited configuration after initialization, you could be better by taking the property approach.
Fairly early on in my app, when I was a lot less experienced than I am now, I wanted to spice up some transitions between view controllers with my own custom animations. Having no idea where to start, I looked around SO for a pattern like MVC that could be accessed from nearly any controller at any time, and as it turns out, a singleton was the way to go.
What I didn't realize is that there seems to be a strong and well-defended hatred of the singleton pattern, and I myself am starting to see why, but that is beside the point.
So, a while later, I decided to move my very same implementation into a category on UINavigationController (after all, it handles transitions!), kept the original classes around for comparison, and am wondering which method would work best. Having thoroughly tested both implementations, I can say without a doubt that they are equal in every way, including speed, accuracy, smoothness, frame-rate, memory usage, etc. so which one is 'better' in the sense of overall maintainability?
EDIT: after reading the well-written arguments you all have made, I have decided to use a singleton. #JustinXXVII has made the most convincing argument (IMHO), although I consider every answer here equally worthy of merit. Thank you all for your opinions, I have upvoted all answers in the question.
I believe the best option is use the category.
Because if you are already using UINavigationController, do not make sense create a new class that will only manage the transition, like you told: (after all, it handles transitions!)
This will be a better option to maintain your code, and you will be sure that the thing do what they expect to do, and if you already have an instance that do the transitions, why create another?
The design patterns, like singleton, factory, and others, need to be used with responsibility. In your case, I do not see why use a singleton, you use it only to no instantiate new objects, you do not really need to have only one instance of it, but you do it because you want only one.
I'll make the case for a singleton object. Singletons are used all over UIKit and iOS. One thing you can't do with categories is add instance variables. There are two things about this:
MVC workflows don't tolerate objects with intimate knowledge of other objects
Sometimes you just need a place to reference an object that doesn't really belong anywhere else
These things go against each other, but the added ability to be able to keep an instance variable that doesn't really have an "owner" is why I favor the singleton.
I usually have one singleton class in all of my XCode projects, which is used to store "global" objects and do mundane things that I don't want to burden my AppDelegate with.
An example would be serializing/archiving objects and unarchiving/restoring. I have to use the same method throughout several classes, I don't want to extend UIViewController with some serializing method to write and read arbitrary files. Maybe it's just my personal preference.
I also might need a quick way to lookup information in NSUserDefaults but not want to always be writing [[NSUserDefaults standardUserDefaults]stringForKey:#"blah"], so I will just declare a method in my singleton that takes a string argument.
Until now i've not really thought too much about using a category for these things. One thing is sure though, I'd rather not be instantiating a new object a hundred times to do the same task when I can have just one living object that sticks around and will take care of stuff for me. (Without burdening the AppDelegate)
I think that the real question is in "design" (as you said, both codes work fine), and by writing down your problem in simple sentences, you will find your answer :
singleton's purpose is to have only one instance of a class running in your app. So you can share things between objects. (one available to many objects)
category purpose is to extend the methods available to a class. (available to one class of objects only ! ok...objects from subclasses too)
what you really want is to make a new transition available to UINavigationController class. UINavigationController, which has already some method available to change view (present modal views, addsubviews, etc.) is built to manage views with transitions (you said it yourself, it handles transitions), all you want to do is adding another way of handling transitions for your navigation controllers thus you would preferably use a category.
My opinion is that what you want to achieve is covered by the category and by doing this you ensure that the only objects which are accessing this method are entitled to use it. With the singleton pattern, any object of any class could call your singleton and its methods (and... it could work nobody knowing how for an OS version n but your app could be broken in n+1 version).
In this implementation, for which there is no need to use a Singleton, there may be no difference at all. That doesn't mean that there isn't one.
A plastic bucket holds as much water as a metal bucket does, and it does it just as well. In that aspect there seems to be no difference between the two. However, if you try to transport something extremely hot, the plastic bucket might not do the job so well..
What I'm trying to say is, they both serve their purposes but in your case there seemed to be no difference because the task was too generic. You wanted a method that was available from multiple classes, and both solutions can do that.
In your case, however, it might be a whole of a lot simpler to use a Category. The implementation is easier and you (possibly) need less code.
But if you were to create a data manager that holds an array of objects that you ONLY want available at one place, a Category will not be up to the task. That's a typical Singleton task.
Singeltons are single-instance objects (and if made static, available from nearly everywhere). Categories are extensions to your existing classes and limited to the class it extends.
To answer your question; choose a Category.
*A subclass might also work, but has its own pros and cons
Why don't you simply create a base UIViewController subclass and extend all of your view controllers from this object? A category doesn't make sense for this purpose.
Singletons, as the name suggests, has to be used when there is a need to be exactly one object in your application. The pattern for the accessor method ensures only this requirement being a class method:
+ (MyClass*) sharedInstance
{
static MyClass *instance = nil;
if (instance == nil) instance = [[MyClass alloc] init];
return instance;
}
If implemented well, the class also ensures that its constructor is private thus nobody else can instantiate the class but the accessor method: this ensures that at any time at most one instance of the class exists. The best example of such class is UIApplication since at any time there might be only one object of this class.
The point here is that this is the only requirement towards singleton. The role of the accessor method is to ensure that there is only one instance, and not that it would provide access to that instance from everywhere. It is only a side effect of the pattern that, the accessor method being static, everybody can access this single object without having a reference (pointer) to it a priori. Unfortunately this fact is widely abused by Objective C programmers and this leads to messed up design and the hatred towards singleton pattern you mentioned. But all in all it is not the fault the singleton patter but the misuse of their accessor method.
Now turning back to your question: if you don't need static / global variables in your custom transition code (I guess you don't) then the answer is definitely go for categories. In C++ you would subclass from some parent BaseTransition class and implement your actual drawing methods. Objective C has categories (that in my opinion is another way that easily messes up the design, but they are much more convenient) where you can add custom functionality even accessing the variables of your host class. Use them whenever you can redeem singletons with them and don't use singletons when the main requirement towards your class is not that it would be only one instance of it.
In objective-c when you are implementing a method that is going to perform a repetitive operations, for example, you need to choice in between the several options that the language brings you:
#interface FancyMutableCollection : NSObject { }
-(void)sortUsingSelector:(SEL)comparator;
// or ...
-(void)sortUsingComparator:(NSComparator)cmptr;
#end
I was wondering which one is better?
Objective-c provides many options: selectors, blocks, pointers to functions, instances of a class that conforms a protocol, etc.
Some times the choice is clear, because only one method suits your needs, but what about the rest? I don't expect this to be just a matter of fashion.
Are there any rules to know when to use selectors and when to use blocks?
The main difference I can think of is that with blocks, they act like closures so they capture all of the variables in the scope around them. This is good for when you already have the variables there and don't want to create an instance variable just to hold that variable temporarily so that the action selector can access it when it is run.
With relation to collections, blocks have the added ability to be run concurrently if there are multiple cores in the system. Currently in the iPhone there isn't, but the iPad 2 does have it and it is probable that future iPhone models will have multiple cores. Using blocks, in this case, would allow your app to scale automatically in the future.
In some cases, blocks are just easier to read as well because the callback code is right next to the code that's calling it back. This is not always the case of course, but when sometimes it does simply make the code easier to read.
Sorry to refer you to the documentation, but for a more comprehensive overview of the pros/cons of blocks, take a look at this page.
As Apple puts it:
Blocks represent typically small, self-contained pieces of code. As such, they’re particularly useful as a means of encapsulating units of work that may be executed concurrently, or over items in a collection, or as a callback when another operation has finished.
Blocks are a useful alternative to traditional callback functions for two main reasons:
They allow you to write code at the point of invocation that is executed later in the context of the method implementation.
Blocks are thus often parameters of framework methods.
They allow access to local variables.
Rather than using callbacks requiring a data structure that embodies all the contextual information you need to perform an operation, you simply access local variables directly.
On this page
The one that's better is whichever one works better in the situation at hand. If your objects all implement a comparison selector that supports the ordering you want, use that. If not, a block will probably be easier.
I have a XML parser which will parse 17 different XML documents (I'm simplifying this).
When the parser has finished its job, it calls the object that did the request.
First way
A single method that looks like
- (void)didReceiveObject:(NSObject *)object ofType:(MyObjectType)type
with MyObjectType being an enum.
In this method, I check the type and redirect the object to the corresponding method.
Second way
There is a callback method for each of the 17 types of object I can receive.
- (void)didReceiveFoo:(MYFoo *)foo
- (void)didReceiveBar:(MYBar *)bar
... and so on
Which way of using delegates will be better?
We had a discussion about this with a colleague and couldn't find one way more appealing than another. It seems like it's just deciding what method to call from the parser or within the delegate....
Even when thinking about adding future methods/delegates callbacks, we don't see any real problem.
Is one of these ways better than the other? Is there another way?
Why not go with
- (void)didReceiveObject:(NSObject *)object
and then inspect the class type?
This seems cleaner and more extensible to me, because it means you can parse other objects in the future without adding more callbacks.
(I know this is the same as option one, but I wanted to point out that your second argument was unnecessary.)
First method:
Pros:
More flexible to future changes.
Cons:
May result in a large switch statement or messy if ... else if ... else statement.
Probably results in a series of explicit methods anyway.
Requires type cast.
Second method:
Pros:
No type casting.
If methods are optional, delegate is only bothered with the objects it's interested in.
Cons:
If methods are not optional and the interface is expanded later, all delegates will have warnings until the new methods are implemented.
If methods are not optional, this can be a lot of methods to implement for every delegate.
Generally when building delegate interfaces I lean towards generics for future extensibility. Changing an API, especially with open source code, can be very difficult. Also, I don't quite understand why you have one XML parser doing so much. You may want to consider a different design. 17 different XML documents seems like a lot. That aside, I'll propose a third method.
Third method:
Create a dictionary that maps strings to blocks. The blocks would probably be of type void(^BlockName)(id obj). Your parser would define a series of strings that will be the keys for your various blocks. For example,
NSString * const kFooKey = #"FooKey";
NSString * const kBarKey = #"BarKey";
// And so on...
Whoever creates the XML parser would register a block for each key they are interested in. They only need to register for the keys they are interested in and it's completely flexible to future change. Since you are registering for explicit keys/objects, you can assert the passed in type without a type cast (essentially Design By Contract). This might be over kill for what you want, but I've found similar designs very beneficial in my code. It combines the pros of both of your solutions. It's main downfall is if you want to use an SDK that doesn't have blocks. However, blocks are becoming a de facto standard with Objective-C.
On top of this you may want to define a protocol that encompasses the common functionality of your 17 objects, if you haven't done so already. This would change your block type to void(^BlockName)(id<YourProtocol> obj).
Here's the decision.
We will implement both and see which way is the more used.
The first way is the easiest and fastest so we will keep it for internal needs.
But we may be shipping this code as a static library so we want to give the minimal amount of information. So we will also stick with the with the second way.
As there should be a big chunk of code for each callback, the generic way will certainly be the big switch statement rbrown pointed.
Thank you for your help.
I wanted to ask you all for you opinions on code smells in Objective C, specifically Cocoa Touch. I'm working on a fairly complex game, and about to start the Great December Refactoring.
A good number of my classes, the models in particular, are full of methods that deal with internal business logic; I'll be hiding these in a private category, in my war against massive header files. Those private categories contain a large number of declarations, and this makes me feel uneasy... almost like Objective-C's out to make me feel guilty about all of these methods.
The more I refactor (a good thing!), the more I have to maintain all this duplication (not so good). It just feels wrong.
In a language like Ruby, the community puts a LOT of emphasis on very short, clear, beautiful methods. My question is, for Objective C (Cocoa Touch specifically), how long are your methods, how big are your controllers, and how many methods per class do you all find becomes typical in your projects? Are there any particularly nice, beautiful examples of Classes made up of short methods in Objective C, or is that simply not an important part of the language's culture?
DISCLOSURE: I'm currently reading "The Little Schemer", which should explain my sadness, re: Objective C.
Beauty is subjective. For me, an Objective-C class is beautiful if it is readable (I know what it is supposed to do) and maintainable (I can see what parts are responsible for doing what). I also don't like to be thrown out of reading code by an unfamiliar idiom. Sort of like when you are reading a book and you read something that takes you out of the immersion and reminds you that you are reading.
You'll probably get lots of different, mutually exclusive advice, but here are my thoughts.
Nothing wrong with private methods being in a private category. That's what it is there for. If you don't like the declarations clogging up the file either use code folding in the IDE, or have your extensions as a category in a different file.
Group related methods together and mark them with #pragma mark statements
Whatever code layout you use, consistency is important. Take a few minutes and write your own guidelines (here are mine) so if you forget what you are supposed to be doing you have a reference.
The controller doesn't have to be the delegate and datasource you can always have other classes for these.
Use descriptive names for methods and properties. Yes, you may document them, but you can't see documentation when Xcode applies code completion, where well named methods and properties pay off. Also, code comments get stale if they aren't updated while the code itself changes.
Don't try and write clever code. You might think that it's better to chain a sequence of method calls on one line, but the compiler is better at optimising than you might think. It's okay to use temporary variables to hold values (mostly these are just pointers anyway, so relatively small) if it improves readability. Write code for humans to read.
DRY applies to Objective-C as much as other languages. Don't be worried about refactoring code into more methods. There is nothing wrong with having lots of methods as long as they are useful.
The very first thing I do even before implementing class or method is to ask: "How would I want to use this from the outside?"
I never ever, never begin by writing the internals of my classes and methods first. By starting of with an elegant public API the internals tend to become elegant for free, and if they don't then the ugliness is at least contained to a single method or class, and not allowed to pollute the rest of the code with it's smell.
There are many design patterns out there, two decades of coding have taught me that the only pattern that stand the test of time is: KISS. Keep It Simple Stupid.
Some general rules of thumb, for any language or environment:
Follow your gut feeling over any advice you have read or heard!
Bail out early!
If needed, verify inputs early and bail out fast! Less cleanup to do.
Never add something to your code that you do not use.
An option for "reverse" might feel like something nice to have down the road.
In that case add it down the road! Do not waste time adding complexity you do not need.
Method names should describe what is done, never how it is done.
Methods should be allowed to change their implementation without changing their name as long as the result is the same.
If you can not understand what a method does from it's name then change the name!
If the how part is complex enough, then use comments to describe your implementation.
Do not fear the singletons!
If your app only have one data model, then it is a singleton!
Passing around a single variable all over the place is just pretending it is something else but a singleton and adding complexity as bonus.
Plan for failures from the start.
Always use for doFoo:error instead of doFoo: from the start.
Create nice NSError instances with end user readable localized descriptions from the start.
It is a major pain to retrofit error handling/messages to a large existing app.
And there will always be errors if you have users and IO involved!
Cocoa/Objective-C is Object* Oriented, not **Class Oriented as most of the popular kids out there that claim to be OOP.
Do not introduce a dumb value class with only properties, a class without methods performing actual work could just as well be a struct.
Let your objects be intelligent! Why add a whole new FooParser class if a fooFromString: method on Foo is all you need?
In Cocoa what you can do is always more important than what you are.
Do not introduce a protocol if a target/action can do.
Do not verify that instances conforms to protocols, is a kind of class, that is up to the compiler.
My 2 cents:
Properties are usually better than old-style getter+setter. Even if you use #dynamic properties - declare them with #property, this is way more informative and shorter.
I personally don't simulate "private" methods for classes. Yes, I can write a category somewhere in the .m(m) file, but since Obj-C has no pure way to declare a private method - why should I invent one? Anyway, even if you really need something like that - declare a separate "MyClassPrivate.h" with a category and include it in the .m(m) files to avoid duplicating the declarations.
Binding. Binding for most Controller <-> UI relations, use transformers, formatters, just don't write methods to read/write controls values manually. It makes code look like something from MFC era.
C++, a lot of code look much better and shorter when written in C++. Since compiler understands C++ classes it's a good point for refactoring, especially when working will a low-level code.
I usually split big controllers. Something more than 500 lines of code is a good candidate for refactoring for me. For instance, I have a document window controller, since some version of the app it extends with image importing/exporting options. Controller grows up to 1.000 lines where 1/2 is the "image stuff". That's a "trigger" for me to make an ImageStuffController, instantiate it in the NIB and put all image-relative code in there.
All above make it easier for me to maintain my code. For a huge projects, where splitting the controllers and classes to keep 'em small results big number of files, I usually try to extract some code into a framework. For example, if a big part of the app is communicating with external web-services, there is usually a straight way to extract a MyWebServices.framework from the main app.