I am a great fan of code generation (from UML) and coming from the Java world, I wonder how I would implement automated bi-directional association management in Objective-C.
Image an association Partner <-> Address, one-to-many and navigable from both ends. What I would like to achieve is that if I append an Address to a Partner that Address object should automatically know about its Partner.
So the implementation pattern would be to have an NSMutableArray* on the Partner side and a Partner* on the Address side. The property on the Address side is easy to implement, as a setPartner:(Partner*)aPartner could automatically insert the Address (self) into the Partner's NSMutableArray managing the addresses. The other side, however, is not so easy to implement. The standard implementation pattern for to-many references in Objective-C seems to be the NSMutableArray obtainable via the get method of the #property. The object in possession of this NSMutableArray could then insert an Address object into the array, which would of course not be updating the other side.
I know that there are other patterns for this kind of association management, for instance, via addTo...() and removeFrom...() methods. But I don't know yet if this would fit with other principles of Cocoa programming or even prevent me from using Cocoa efficiently. I am thinking about Interface Builder here. Not much experience, but I have seen something called an ArrayController which seems to be quite handy but which also seems to expect an NSMutableArray type property to work with. And if this guy inserts objects into the array I need to intercept that and make the other side adjustment.
As a Java programmer I would tend to subclass NSMutableArray now and override some of its methods which could then manipulate the other end. Would this be possible at all? I read about categories but so far I have understood that I could only add methods to a class this way and not override them nor add to the structure of it. Or should it be method forwarding? I am confused right now. If you could point me into the right direction of thinking it would be so great. Thanks a lot!
Welcome to Cocoa. Do not subclass built-in collections. You will go insane.
Allow me to clarify: in Cocoa, we have these things called "Class Clusters". Clusters are a hierarchy of private classes that all have a common, public superclass. In this case, NSArray is the public superclass, and there are private subclasses that are the actual array implementations. This presents a really difficult challenge when subclassing, because you don't know what class (or classes) you would need to subclass.
The common work-around is to create a new NSObject subclass that "wraps" an NSArray (ie, it has the array as an instance variable ["field"]), and then you invoke methods on the custom wrapper, and the wrapper holds all the custom logic you need.
As to answer your question, I've found that when I have this sort of set up where I need to maintain one-to-one, one-to-many, or many-to-many relationships automatically, there's nothing that beats using CoreData. CoreData is a built-in framework that's more or less like an object store. One of the truly awesome things that it does is handle relationship integrity, which is what you're looking for.
Related
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.
I’m fairly new to OO. If I have two classes A and B that need to exchange data, or call each other’s methods, I need to be able to access an instance of class B from class A. Should I maintain the address of the instance object in a global variable? Should I appoint a (singleton) master class, and make (pointers to) instances of A and B properties of the master class? (AppDelegate comes to mind.)
Is there a straightforward by-the-book way to implement this? Somehow I‘m missing some "best practice" here. I’ve looked through Apple's examples, but didn't find an answer.
EDIT: Since I'm fairly new to MVC design patterns, my question is essentially "Who creates who"?
We're talking about an Audio Player here. 1. When the user selects a song, the UI displays its waveform by creating a viewController which creates the appropriate view. 2. When the user hits play, the UI displays a timeline while the song is playing by overlaying a new view over the waveform. Now, the latter view needs some info from the waveform display viewController. Right now, I'm storing a pointer to the viewController in an instance variable of my appDelegate. This works, but feels extremely strange.
Should I outsource the info that is needed by both classes to some third entity that every class can access easily?
Classes aren't simply departments of code. They are templates for the creation of objects, which you should think of as actors in your program, doing things within their areas of responsibility (which you define—you decide what each object does) and interacting with each other.
While you can handle a class as you would an object, classes generally do not talk to each other. Most of the time, you will create and use instances of the classes—which is what we normally mean by “objects”—and have those talking to each other. One object sends another a message, telling the receiver to do something or changing one of the receiver's properties. These messages are the interactions between your program's objects.
Those weird expressions in the square brackets are message expressions. Nearly everything you'll do with a class or object will involve one or more messages. You can send messages to classes the same as to objects, and classes can send messages just as objects can.
In Cocoa and Cocoa Touch, you typically have model objects, view objects, controller objects, data objects (such as NSString, NS/UIImage, and NSURL), and helper objects (such as NSFileManager). The classes you'll write for your application will mainly be model, view, and controller objects (MVC). The model represents (models) what the user will see themselves manipulating; the view displays the model to the user; the controller implements logic and makes sure the model gets saved to and loaded from persistent storage.
For more information, see Object-Oriented Programming in Objective-C and the Cocoa Fundamentals Guide.
Since I'm fairly new to MVC design patterns, my question is essentially "Who creates who"?
Controllers create and load the model, and load the views, and pass the model to the view for display. Certain controllers may also create other controllers.
It's good to keep a straightforward tree-like graph of ownership from a single root of your program—typically the application object—down through controllers to leaf objects in the models and views. If two objects own each other, that's a problem. If an object is not owned by anything outside of its own class (a singleton), that's usually a problem as well—a sign you need to think some more about where that code belongs. (Helper objects are the main exception; most of those are singletons. Again, see NSFileManager for an example. But they are few and far between.)
Further situation analysis require more information. At first place you should more specify the relation between classes and what exactly do you mean by exchanging data.
Singletons should be generally avoided. If you want to exchange information it is usually sufficient to provide for example instance of the class A to the instance of the class B by some method or constructor. The instance of B is then capable of calling public methods (and accessing public properties) of the instance of A.
A little bit of "best practices" can be learn by searching up "Design Patterns".
You should decide if one class can be an object of another class (encapsulation), or if one class can inherit from the other class (inheritance). If neither of these is an option, then maybe you could make one class (or some of its members) static?
Thanks for your contributions. Additionally, I found information on this page very useful. It lays out MCV considerations for cocoa in a hands-on way and practical language.
I've recently discovered categories and was wondering when it might be appropriate to use them in a user defined class/new class. For example, I can see the benefits of adding a category to an existing class like NSString, but when creating a new class what would be the advantage of adding a category to this rather than just implementing a normal method?
Hope this makes sense.
Many thanks
Jules
The answer isn't really any different for your own classes than it is for framework classes. If you have multiple projects, you'll likely end up sharing some classes between them. However, you may want to extend some of your classes so that they work more easily with a specific project, but not want to include those extra methods in your other projects, where they might not make sense. You can use a category to extend your class without needing to subclass.
If I understand your question correctly, creating a "new class" is always "subclassing" because you're subclassing NSObject at the very least.
You could use categories on a new class to separate out sections of responsibility of a complex class. For example, all the basic functionality (instance variables, accessors, description, etc.) can go in one file (the "main" class file) while all methods to support a protocol (such as NSTableViewDataSource) can go in another.
Some take this approach to keep things "neat". I'm a firm believer in "if it's my own custom class, all its code should be in one file" so I do not personally do this. I demarcate different logical aspects of the class' code with "#pragma mark Some Section Name" to help navigation and readability. Your mileage may vary.
Adding a Category on NSString is useful when you want to call a method on every single NSString instance you will encounter. This is a real improvement over inheritance for this kind of object because they are used by the core framework and you don't have to convert a NSString object to your subclass when you want to call your custom method.
On the other hand, you can just put methods in, no instance variables.
In the book Refactoring by Martin Fowler, he has a section titled "Introduce Foreign Method" (A server class you are using needs an additional method, but you can't modify the class.) That's what categories are good for.
That said, there are times when using a category, instead of changing the class, is appropriate. A good example on using a category, even though you could change the server class, is how Apple handled the UIViewController MediaPlayer Additions. They could have put these two methods in UIViewController itself but since the only people who would ever use them are people who are using the Media Player framework, it made more sense to keep the methods there.
We know that in Objective-C there are two main root classes: NSObject and NSProxy. There are other roots (mainly for private and legacy purposes) like Object, and NSLeafProxy.
Defining a new root is fairly trivial:
#interface DDRoot <NSObject>
#end
#implementation DDRoot
//implement the methods required by <NSObject>
#end
My question is: why would you ever want to define a new root class? Is there some use-case where it's necessary?
There are two primary reasons to create a new root class; proxying & a new object model.
When proxying, it can be useful to implement a new root class such that you can basically handle any and all of the class/object's behaviors in a custom fashion. See NSProxy.
The Objective-C runtime is flexible enough that you can support a new object model quite easily (where easily discounts the inherent complexity of creating such a beast in the first place). Actually, many of the behaviors that are considered inherent to the runtime -- KVC, KVO, etc.. -- are implemented as a part of the NSObject class itself.
I know of at least one company that -- as of about 8 years ago, at least -- had implemented their own object model as a part of building their ~500k LOC financial analysis engine.
The key, though, is that if you go this route, you don't try to make your classes interact with Foundation/CF/AppKit/UIKit, etc. If you need that, just subclass NSObject already!
It is interesting to note that NSManagedObject is effectively a root class in that it does some pretty seriously custom stuff, but it is a subclass of NSObject so subclasses of NSManagedObject are inter-operable with the rest of the system.
As far as I can tell, there should be no reason for creating your own root class, because short of implementing all of the NSObject protocol methods yourself, you're going to be missing out on a lot of functionality, and going to be making a lot of calls to the Objective-C runtime that should essentially be done for you.
Unless you really had to implement the protocol differently from the default (NSProxy is a special case that does have to), you shouldn't need to make your own root class. I mean, you'd have to be writing a class that cannot fundamentally be represented by NSObject and the protocol as implemented by Apple, and in that case, why are you even writing it in Objective-C?
That's what I think. Maybe someone can come up for a creative use for it.
(People researching the topic should go look at the NSObject Class Reference, NSObject Protocol Reference, 'Core Competencies: Root Class' document, and the 'Root Class' section of the Fundamentals Guide: Cocoa Objects document.)
Objective-C and Cocoa are separate things, and in principle it’s possible to define entirely new application frameworks that don’t use Foundation. The financial analysis people bbum mentioned are a practical example, and I believe they’re still around.
Another use is to make a proxy that’s more minimal than NSProxy, as Mike Ash does here.
Oh, and the private NSInvocationBuilder is a root class, presumably for the same reasons as Mike’s proxy. Capturing invocations for later use is something one might want to recreate.
Companies like the OmniGroup have defined a version of NSObject to use as their own base class for everything.
It's essentially a subclass of NSObject with some debug stuff. Other than that, it's usually a terrible idea to fight the framework.
Find Omni's code here:
https://github.com/omnigroup/OmniGroup
Can some one explain to me the difference between categories and inheritance in Objective C? I've read the entry in Wikipedia and the discussion on categories there doesn't look any different to that of inheritance. I also looked at the discussion on the topic in the book "Open iPhone Development" and I still don't get it.
Sometimes, inheritance just seems like more trouble than it is worth. It is correctly used when you want to add something to an existing class that is a change in the behaviour of that class.
With a Category, you just want the existing object to do a little more. As already given, if you just want to have a string class that handles compression, you don't need to subclass the string class, you just create a category that handles the compression. That way, you don't need to change the type of the string classes that you already use.
The clue is in the restriction that categories only add methods, you can't add variables to a class using categories. If the class needs more properties, then it has to be subclassed.(edit: you can use associative storage, I believe).
Categories are a nice way to add functionality while at the same time conforming to an object oriented principle to prefer composition over inheritance.
Edit January 2012
Things have changed now. With the current LLVM compiler, and the modern, 64-bit runtime, you can add iVars and properties to class extensions (not categories). This lets you keep private iVars out of the public interface. But, if you declare properties for the iVars, they can still be accessed / changed via KVC, because there is still no such thing as a private method in Objective-C.
Categories allow you to add methods to existing classes. So rather than subclass NSData to add your funky new encryption methods, you can add them directly to the NSData class. Every NSData object in your app now has access to those methods.
To see how useful this can be, look at: CocoaDev
One of favorite illustrations of Objective-c categories in action is NSString. NSString is defined in the Foundation framework, which has no notion of views or windows. However, if you use an NSString in a Cocoa application you'll notice it responds to messages like – drawInRect:withAttributes:.
AppKit defines a category for NSString that provides additional drawing methods. The category allows new methods to be added to an existing class, so we're still just dealing with NSStrings. If AppKit instead implemented drawing by subclassing we'd have to deal with 'AppKitStrings' or 'NSSDrawableStrings' or something like that.
Categories let you add application or domain specific methods to existing classes. It can be quite powerful and convenient.
If you as a programmer are given a complete set of source code for a code library or application, you can go nuts and change whatever you need to achieve your programming goal with that code.
Unfortunately, this is not always the case or even desirable. A lot of times you are given a binary library/object kit and a set of headers to make do with.
Then a new functionality is needed for a class so you could do a couple of things:
create a new class whole instead of a stock class -- replicating all its functions and members then rewrite all the code to use the new class.
create a new wrapper class that contains the stock class as a member (compositing) and rewrite the codebase to utilize the new class.
binary patches of the library to change the code (good luck)
force the compiler to see your new class as the old one and hope it does not depend on a certain size or place in memory and specific entry points.
subclass specialization -- create subclasses to add functionality and modify driver code to use the subclass instead -- theoretically there should be few problems and if you need to add data members it is necessary, but the memory footprint will be different. You have the advantage of having both the new code and the old code available in the subclass and choosing which to use, the base class method or the overridden method.
modify the necessary objc class with a category definition containing methods to do what you want and/or override the old methods in the stock classes.
This can also fix errors in the library or customize methods for new hardware devices or whatever. It is not a panacea, but it allows for class method adding without recompiling the class/library that is unchanged. The original class is the same in code, memory size, and entry points, so legacy apps don't break. The compiler simply puts the new method(s) into the runtime as belonging to that class, and overrides methods with the same signature as in the original code.
an example:
You have a class Bing that outputs to a terminal, but not to a serial port, and now that is what you need. (for some reason). You have Bing.h and libBing.so, but not Bing.m in your kit.
The Bing class does all kinds of stuff internally, you don't even know all what, you just have the public api in the header.
You are smart, so you create a (SerialOutput) category for the Bing class.
[Bing_SerialOutput.m]
#interface Bing (SerialOutput) // a category
- (void)ToSerial: (SerialPort*) port ;
#end
#implementation Bing (SerialOutput)
- (void)ToSerial: (SerialPort*) port
{
... /// serial output code ///
}
#end
The compiler obliges to create an object that can be linked in with your app and the runtime now knows that Bing responds to #selector(ToSerial:) and you can use it as if the Bing class was built with that method. You cannot add data members only methods and this was not intended to create giant tumors of code attached to base classes but it does have its advantages over strictly typed languages.
I think some of these answers at least point to the idea that inheritance is a heavier way of adding functionality to an existing class, while categories are more lightweight.
Inheritance is used when you're creating a new class hierarchy (all the bells and whistles) and arguably brings alot of work when chosen as the method of adding functionality to existing classes.
As someone else here put it... If you are using inheritance to add a new method for example to NSString, you have to go and change the type you're using in any other code where you want to use this new method. If, however, you use categories, you can simply call the method on existing NSString types, without subclassing.
The same ends can be achieved with either, but categories seem to give us an option that is simpler and requires less maintenance (probably).
Anyone know if there are situations where categories are absolutely necessary?
A Category is like a mixin: a module in Ruby, or somewhat like an interface in Java. You can think of it as "naked methods". When you add a Category, you're adding methods to the class. The Wikipedia article has good stuff.
The best way to look at this difference is that:
1. inheritance : when want to turn it exactly in your way.
example : AsyncImageView to implement lazy loading. Which is done by inheriting UIView.
2. category : Just want to add a extra flavor to it.
example : We want to replace all spaces from a textfield's text
#interface UITextField(setText)
- (NSString *)replaceEscape;
#end
#implementation UITextField(setText)
- (NSString *)replaceEscape
{
self.text=[self.text stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
return self.text;
}
#end
--- It will add a new property to textfield for you to escape all white spaces. Just like adding a new dimension to it without completely changing its way.