What describes objective-C and Cocoa Bindings best? - objective-c

I have trouble understanding Cocoa Bindings. Can someone explain me what this is all about, in an way that is humanly perceivable?

Bindings is a system for connecting your views to your controllers without writing a lot of glue code to make them explicitly talk to each other. All you have to do is set up properties in both classes* and hook up the binding in IB.
The traditional approach is that the view has one or more outlets to talk to the controller (the most generic examples being delegate and target) and the controller has outlets to talk to the views. When the controller updates the model, it sends (for example) [view modelChange:newModelObject]. When the view wants to update the model, it sends some delegate message to its delegate (the controller), such as NSText's textDidChange:.
With Bindings, all you have to do in code is implement properties on the view and properties on the controller, then expose one or more properties of the view as bindings*. Then you only need to hook up the binding. If it's a Cocoa class, this is cake: just set it up in IB. If it's a custom class of your own, you'll probably write the bind:toObject:withKeyPath:options: message yourself (not much harder).
Let me restate that: With Bindings, your entire glue code (most of the time) is [view bind:#"viewProperty" toObject:self withKeyPath:#"controllerProperty.modelProperty" options:options]; in the controller. Everything else is handled by the Bindings and KVO systems behind the scenes, and by your properties' accessors.
The disadvantage is that you must strictly conform to Cocoa Bindings' requirements. These are simple, but a lot of older applications are designed in a way that doesn't fit Cocoa Bindings.
You must create real model objects, not just pass primitive objects (e.g., arrays of dictionaries) around. If you're using Core Data, this is easy: your managed objects are model objects.
You must either write your accessors correctly or synthesize the correct accessors. For example, an NSString property should always be #property(copy), never #property(retain) (because otherwise, you will find yourself retaining someone else's mutable string, which they will then mutate while you're holding it).
You must only change properties of your model objects by their properties (model.foo = bar) or by accessor messages ([model setFoo:bar]), never by direct instance variable access. (Obvious exception for accessor methods themselves, if you've written your own, because they must access the instance variable directly.)
There are two advantages:
You can write a brand new view class without having to rip out a lot of glue code. The most you'll have to delete is some bind:::: messages for the old view's properties. If, a couple of years down the road, you decide that your current view just can't scale to your application's forthcoming capabilities, this gives you the flexibility to rip it out and start afresh with the minimum of pain.
More importantly, the less code you have to read, the easier it is to read it.
*And, according to the documentation, implement a KVO observation method in the view class, but I've never actually had to do this. I filed a documentation bug.
Added 2009-03-07: Ah, found a citation. “NSView subclasses can expose additional key-value-coding/key-value-observing compliant properties as bindings by calling the class method exposeBinding: for each of the properties.” —NSKeyValueBindingCreation So you shouldn't need to implement a KVO observation method.

Previous answer is very comperhensive and good, I'd just thought I'd add an answer explains what it is at its core without involving Cocoa or Objective-C specifically. That is because the concept itself is language agnostic although dynamic languages like Objective-C makes it a lot easier than more static language like C++.
Example
Say you have two objects M and V. M has methods:
setX(int x);
setY(int y);
int getX();
int getY();
While V has methods:
setA(int x);
setB(int y);
int getA();
int getB();
One way of looking at this is that M has properties x and y and V has properties a and b. You want a change of property x to cause a change in property b and a change in y to cause a change in a.
By change in property x we mean e.g.:
M.setX(10)
where previously
M.getX() != 10
So we want a call of setX on M to cause a call to setA on V.
What bindings allow you to say is that property b on object V is bound to property x on object M. And then this updating is handled automatically. You as a coder don't have to write code that checks if x is changed and then call setB on V. Bindings takes care of this automatically.
Summary
Bindings allows you to bind two properties together that exist on two different objects, so that changing the value of one of the properties causes the dependant property in the other object to change to the same value.

Related

How to bind NSTableView to a custom collection class?

I know how to bind a NSTableView to an NSArray via NSArrayController.
But what about binding NSTableView to MyCustomCollection? What do the bindings look like? Can I still use NSArrayController and just conform to a protocol in MyCustomCollection? Or should I use a different controller object? What does MyCustomCollection need to conform to?
This is hard to answer completely or specifically without knowing a lot more about your collection class. Almost certainly creating a custom collection class is the wrong thing to do. You should definitely elaborate on the reasons you feel this is necessary and your implementation. Be prepared to consider your reasons aren't good enough to justify jamming a custom collection into an NSArrayController or that it's not even possible to do exactly what you want (at least the way you're trying to do it).
Also note Cocoa collection classes are (I think all) members of a class cluster. This makes "doing it right" a significantly more complex challenge and makes subclassing an existing Cocoa collection class a Bad Idea™ if you have to ask how ("if you have to ask, you're not ready to try it" conceit, albeit justified).
I believe as long as your class responds to the same selectors as does (at least) NSArray (if not NSMutableArray if your class is mutable), including the Key Value Coding collection accessor methods, it should probably work alright. Since your table (or, more likely, its columns) is bound to the array controller, that part should work the same. Since NSArrayController inherits -content / -setContent: from NSObjectController and these methods take an id argument, I believe it likely uses the KVC accessor methods I referenced to get at the collection's members.
But I could be wrong... :-)

How to share a Data object among a set of delegates?

Following the MVC pattern stressed in various Objective-C programming guides, when I use Model with Controller, I should set the Controller as the delegate of the given Model. Now I have a huge Data object that's very expensive to create, and there're a few Controllers that need to work with this Data object. As long as the delegate property is set to the right Controller the Data object will work fine for THAT controller. Is there a way to share this model among these controllers?
I've brainstormed for a while, but haven't thought of any especially good solutions. A few things that I've come up
use notification center (but it seems expensive to set up such a relationship just for this specific case)
make each method of the Data object take a delegate argument: this is what I'm currently using now, but it is clunky and is reaching its limit
Edit
Thanks for people who have suggested to me using an NSArray. I think I forget to include this subtlty:
For my case say one of the delegates, A, wants to query the Data object by using one of its specific methods. The result would be correct if the delegate field of the Data object is set to A. But from what I understand using an array and calling the method on every delegate wouldn't give me the answer I want.
In fact since my Data object couldn't know which delegate is calling it, it can't give back the correct result even if it knows about all the delegates it should be associated with
Any thought on this?
You could make an NSArray with delegates and then just call the method on every delegate in your array. (Watch out for retain cycles).
If you don't want to use notifications you can try using a multicast delegate approach. In this you would keep an NSMutableArray of delegates instead of a single one. So instead of setting the delegate you would add and remove delegates from your delegate array. When calling a delegate you would then call that delegate method on each delegate in the array, checking each one if it response to that particular callback.
You can also control the order the delegates are called in if you so wish since you create and manage the delegate array yourself.
What I ended up doing is setting up another level of indirection - each Controller will be communicating with a 'middleware' object, which in turn communicates with the Data object. In this way, the common delegate-delegatee approach is preserved while the Data object only needs to be created once - at the expense of added 'middleman' object for each Controller.
In my example, the 'middleware' object will have a Controller set as its delegate property, and when that Controller wants to know information about the Data object, the 'middleware' object will then use its delegate property to query information from the Data object.

confusion over Objective-c views, delegates, and outlets

I am trying to teach myself objective-c, but coming from a Python/Java background, it is proving very difficult. I tried to post a bunch of points I am confused on, but it was marked as too vague, so I'll break it into sections.
First, every example of a delegate and outlet I've found uses cocoa view code to get the idea across. Unfortunately, I don't yet understand enough of the code to grasp the example's point. So, can anyone provide a more basic example of a delegate? My understanding is that it is a way of subclassing; how is this better than traditional subclassing? Why does every cocoa project automatically include appDelegate.m? Can delegates be used for other purposes, not just GUI stuff?
Okay, I think I see. So a delegate is a class that conforms to the protocol of some other class. A protocol is simply a list of methods and variables that have to (or can, if set to optional) be implemented in the delegate class. To make a delegate, you have to use the #interface keyword, then the name of your delegate, then (in < > signs) the protocol name? So if class c1 wants to set itself up as a delegate of class c, class c must first specify a protocol, right? You would then be able to implement everything in c's protocol in c1:
#interface c1;
I feel like I'm missing some bits there, but hopefully I have the concepts right. :) This also explains the mysterious less- and greater-than signs; they declare what interface the delegate implements.
Outlets are similarly always tied to view code. They seem to be some kind of inter-object messaging system. Is that right? Again, an example of a basic outlet that is not mixed in with complex GUI statements would be great.
So outlets are never needed? I know that IBOutlet and IBAction are not needed except for use with Interface Builder, but I thought outlets were more general than that? The docs seemed to indicate that they are not even specifically for interfaces, but could be used for anything.
Thanks in advance for any help.
Update: Delegates don't have to conform to protocols. Protocols just make it easier to require some classes to have methods. It allows you to know for certain an object one has set as a delegate implements a certain method so you can call it safely, and allows the compiler to verify that method is indeed implemented (if you declare a delegate instance variable as id<SomeProtocol> delegate, the compiler will give a warning or error if you try to set delegate to an object of a class that doesn't conform to SomeProtocol.
Protocols help ensure safety, but they're not strictly necessary. A class can have a delegate (or multiple!), and they don't have to conform to any protocols at all.
As for outlets, no, they're specifically and only used with Interface Builder. The IBOutlet and IBAction keywords have no effect on code (they're even stripped out before compile time) - they're only markers for Interface Builder to look for so it knows which properties and methods should be accessible within the interface. The term 'outlet' is a direct reference to something marked as an IBOutlet, and is really not used in any other context that I can tell.
Again, it's okay if you don't understand this right away. Think it over a bit, and at some point, it'll just 'click'. I was caught up on delegates for a long time, just like this, before one day, I realized that delegates really aren't any special. They're regular objects referenced by other objects - it's just that this design pattern has a special name (delegation), and these objects are only called delegates. They could just as easily be called gyros or falafels, and the net effect would be the same. :P
You don't need to name an object delegate for it to be a delegate; it's just a convention.
About delegates: the first thing to understand, and this got me for a while until I had the proper "Aha!" moment, is that there is nothing special about a "delegate". The word "delegate" is just a title for a type of object that another class depends on, very often for content or decision-making. A developer will use a delegate when they don't want to (or can't) tie one of their classes to another class by name - it's an Object-Oriented way of decoupling and making classes more generic.
Now, very often, classes will require delegates to have specific methods they rely on, and one way to ensure that is with a protocol (more commonly known as an interface in Java). Protocols define a list of methods; classes "conform" to a protocol if they declare they do in their interface (e.g. #interface IFObject : NSObject <SomeProtocol> { ... }) and if they implement all the methods they're required to. Protocols can have optional methods as well.
This model is used often with view controllers, views, and the GUI in general because many AppKit and UIKit classes are written to be as generic as possible. NSTableView, for instance, implements the most basic behavior it can possibly implement without requiring any implementation-specific information; for the rest, it relies on other objects, ones that conform to the NSTableViewDelegate and NSTableViewDataSource protocols. Any object can conform to the protocols, as long as they implement the right methods (and in this case, a controller class will usually implement methods from both protocols, but it doesn't have to be so). In fact, one easy way to understand this topic better is to take a look at NSTableView - it's got a delegate property and a dataSource property, but in effect, they're no different. delegate could be called monkeyButt, and the concept would still work. The key is to not treat delegates as a black box - there's nothing special about them.
Delegates can be also used for non-GUI purposes; one concrete example, as you mention, is the app delegate. NSApplication sends a delegate notifications to let it know when the application has been launched (among other things), so it can set up shop. Again, any object can be a delegate to any other object, for any purpose. It's simply a convention.
Briefly about outlets: as others have mentioned, outlets are simply connections between an interface defined in an XIB and your code. They're a way of letting Xcode link up the interface to the appropriate elements so that when your application loads the interface file, it can load up the right pieces of code or execute them.
They're generally an easier way of setting up an interface - they're not strictly necessary (you can create an interface programmatically, without using an XIB file), but if you do decide to go the XIB route, they're how you relate your interface to your code.
A delegate is an object that is delegated some task by an object it declares itself the delegate of. Let's say an object does some task and then needs to notify the object that "owns" it, so to speak. In order to allow the object to work under any conditions, it cannot be allowed to know what type of object it should contact, so we set its delegate and adhere to its protocol. Setting the object's delegate is like saying "Here's the object I want you to use contact with the messages declared in your protocol. I promise the object actually implements the methods in the protocol." For example, you might see this.
#protocol SpriteDelegateProtocol
#required
- (void) projectionMatrix;
#optional
- (void) animation:(int)animationIndex willCompleteFrameNumber:(int)frame forSprite:(id)sender;
#end
#interface Sprite
#property (nonatomic, assign) id<SpriteDelegateProtocol> delegate;
#end
The interface for our sprite object declares that it has a property called a delegate, which is of type id. It can be any object, but it must adhere to the protocol in the triangle brackets. If it says it adheres to the protocol, it has to implement the methods declared under the #required and can implement the ones listed under the #optional. It's up to us to determine whether or not our delegate actually implements the optional methods using something like respondsToSelector:. We might even store the return value if we had a lot of methods to do that for.
The application delegate is special in that it is the delegate to our UIApplication object. It receives messages on application state, such as applicationDidEnterBackground:. You can see what methods are in the protocol adhered to by our application delegate here.
Delegates can be used with any object. Any object can say it has a delegate property to set, and that it must have the following methods as shown above. The protocol is essentially a portable interface that can be used to tell another object what we need it to implement so that we can call said methods to delegate some portion of functionality out to it. We can notify our delegate when a task has completed, ask it to give us information (typically called a data source instead of a delegate so that they can be different objects if you want) or ask it whether or not we should do some task at all.
An outlet is a way of connecting a view instantiated in a NIB or storyboard to a property in its controller. So, if you place a UIViewController into your main storyboard and change its class to MyGreatControllerSubclass then proceed to place a button in that controller's view, you might want to hook that button up to an "outlet" (property) in the controller's interface so that you can access the button from the controller later.
No delegates are not a way of subclassing. I also came from Java and have been doing O-C for almost 5 years now.
Delegates generally conform to Protocols, which are the equivalent of Interfaces. What's great about that is it leaves you a lot of flexibility in how you implement the things that are covered by the delegate. So for instance, you will see that Table Views can be implemented by extending UITableViewController or implementing the delegate. That way, if you have a composed view where a user is selecting items from one table and putting them into another, you can do a single controller and have it perform the delegation for both views.
The best way to think about delegates is as examples of message/event oriented callbacks. Have you ever heard the saying that what makes a Framework different from ordinary programming is, with a Framework, it tells you what it wants you to do to ensure the results you seek? That is what delegation is. I was doing a Collection View last night and could not get the edit menu to come up. Just provide delegation of three methods, know nothing about how the menu is invoked, where the Long Press gesture handler is, etc.
Note that Delegates are the glue that makes Dependency Injection unneeded in the O-C world. I prefer them.
Delegates are the common design pattern (http://en.wikipedia.org/wiki/Delegation_pattern), they are not objective-c specific.
Outlets make possibly the binding of Controller and View (GUI). May be you know the MVC paradigm (model-view-controller)? So you build your GUI (the View from MVC) with Interface Builder and bind the elements of this GUI such as Buttons, Text fields and so on to your Obj-C code (the Controller from MVC) using outlets.
Take a look at this post: Conforming Objective-C’s Protocols in C# Codes
Don't worry about the word "C#" in the title, you could just ignore that part. The main part of this post talks about protocols and delegates in Objective-C. This might be helpful.

In Objective-C, if #property and #synthesize will add getter and setter, why not just make an instance variable public?

In Objective-C, we can add #property and #synthesize to create a property -- like an instance variable with getter and setter which are public to the users of this class.
In this case, isn't it just the same as declaring an instance variable and making it public? Then there won't be the overhead of calling the getter and setter as methods. There might be a chance that we might put in validation for the setter, such as limiting a number to be between 0 and 100, but other than that, won't a public instance variable just achieve the same thing, and faster?
Even if you're only using the accessors generated by #synthesize, they get you several benefits:
Memory management: generated setters retain the new value for a (retain) property. If you try to access an object ivar directly from outside the class, you don't know whether the class might retain it. (This is less of an issue under ARC, but still important.)
Threadsafe access: generated accessors are atomic by default, so you don't have to worry about race conditions accessing the property from multiple threads.
Key-Value Coding & Observation: KVC provides convenient access to your properties in various scenarios. You can use KVC when setting up predicates (say, for filtering a collection of your objects), or use key paths for getting at properties in collections (say, a dictionary containing objects of your class). KVO lets other parts of your program automatically respond to changes in a property's value -- this is used a lot with Cocoa Bindings on the Mac, where you can have a control bound to the value of a property, and also used in Core Data on both platforms.
In addition to all this, properties provide encapsulation. Other objects (clients) using an instance of your class don't have to know whether you're using the generated accessors -- you can create your own accessors that do other useful stuff without client code needing changes. At some point, you may decide your class needs to react to an externally made change to one of its ivars: if you're using accessors already, you only need to change them, rather than make your clients start using them. Or Apple can improve the generated accessors with better performance or new features in a future OS version, and neither the rest of your class' code nor its clients need changes.
Overhead Is Not a Real Issue
To answer your last question, yes there will be overhead—but the overhead of pushing one more frame and popping it off the stack is negligible, especially considering the power of modern processors. If you are that concerned with performance you should profile your application and decide where actual problems are—I guarantee you you'll find better places to optimize than removing a few accessors.
It's Good Design
Encapsulating your private members and protecting them with accessors and mutators is simply a fundamental principle of good software design: it makes your software easier to maintain, debug, and extend. You might ask the same question about any other language: for example why not just make all fields public in your Java classes? (except for a language like Ruby, I suppose, which make it impossible to expose instance variables). The bottom line is that certain software design practices are in place because as your software grows larger and larger, you will be saving yourself from a veritable hell.
Lazy Loading
Validation in setters is one possibility, but there's more you can do than that. You can override your getters to implement lazy loading. For example, say you have a class that has to load some fields from a file or database. Traditionally this is done at initialization. However, it might be possible that not all fields will actually be used by whoever is instantiating the object, so instead you wait to initialize those members until it's requested via the getter. This cleans up initialization and can be a more efficient use of processing time.
Helps Avoid Retain Cycles in ARC
Finally, properties make it easier to avoid retain loops with blocks under ARC. The problem with ivars is that when you access them, you are implicitly referencing self. So, when you say:
_foo = 7;
what you're really saying is
self->_foo = 7;
So say you have the following:
[self doSomethingWithABlock:^{
_foo = 7;
}];
You've now got yourself a retain cycle. What you need is a weak pointer.
__block __weak id weakSelf = self;
[self doSomethingWithABlock:^{
weakSelf->_foo = 7;
}];
Now, obviously this is still a problem with setters and getters, however you are less likely to forget to use weakSelf since you have to explicity call self.property, whereas ivars are referenced by self implicitly. The static analayzer will help you pick this problem up if you're using properties.
#property is a published fact. It tells other classes that they can get, and maybe set, a property of the class. Properties are not variables, they are literally what the word says. For example, count is a property of an NSArray. Is it necessarily an instance variable? No. And there's no reason why you should care whether it is.
#synthesize creates a default getter, setter and instance variable unless you've defined any of those things yourself. It's an implementation specific. It's how your class chooses to satisfy its contractual obligation to provide the property. It's just one way of providing a property, and you can change your implementation at any time without telling anyone else about it.
So why not expose instance variables instead of providing getters and setters? Because that binds your hands on the implementation of the class. It makes other acts rely on the specific way it has been coded rather than merely the interface you've chosen to publish for it. That quickly creates fragile and inter-dependent code that will break. It's anathema to object-oriented programming.
Because one would normally be interested in encapsulation and hiding data and implementations. It is easier to maintain; You have to change one implementation, rather than all. Implementation details are hidden from the client. Also, the client shouldn't have to think about whether the class is a derived class.
You are correct... for a few very limited cases. Properties are horrible in terms of CPU cycle performance when they are used in the inner loops of pixel, image and real-time audio DSP (etc.) code. For less frequent uses, they bring a lot of benefits in terms of readable maintainable reusable code.
#property and #synthesize is set are getting getter and setter methods
other usage is you can use the that variable in other classes also
if you want to use the variable as instance variable and your custom getter and setter methods you can do but some times when you set the value for variable and while retrieving value of variable sometimes will become zombie which may cause crash of your app.
so the property will tell operating system not to release object till you deallocate your object of class,
hope it helps

Avoiding coupling in a document-based Cocoa app?

I'm new to Mac programming and I'm working on a document-based application.
My NSDocument subclass creates a NSWindowController subclass. This window controller creates two NSViewController subclasses as well.
Sometimes, a change in one of the views of a NSViewController needs to notify the NSDocument and/or the main model class. Also, a change in the model needs to be notified to every/some view(s).
My question is: what is the best approach so that there is no (or minimum) coupling? I know there are several choices, but I'm not sure which one suits best for my application as I'm newbie not to programming but to Cocoa and especially NSDocument:
KVO. Looks nice and easy to implement, but I don't like the idea of not explicitly notifying the observer(s) about a change (AFAIK, self.someProperty = newValue does automagically notify observers), and don't like the fact that you have to register to property names which could change in time.
Notifications. I know what they are and I've used them for iOS. But I've read somewhere that they are not guaranteed to be sent immediately to observers. Is it true? If not, do you see them as a good approach for a document-based app?
Delegates. Yes, under normal conditions (or what I've usually seen), a class has one delegate. But creating an array of delegates works as well (just tested it). The problem I see here is that every time I need to notify the delegates I have to loop through them, make sure they respond to a method, and call that method.
Are there any other alternatives I'm missing?
KVO by a controller class is the most common way to do coupling between a model and its view(s). In fact, Cocoa Bindings, which are intended to mostly eliminate code in the controller layer, are based on KVO. It is true that KVO/KVC relies on property names, and that if those change, you'll have to change the bindings or KVO setup connecting your view. However, it's not usually feasible to make your views completely unaware of the underlying model specifics, so I don't see this as a problem.
My recommendation would be to use Cocoa Binding where you can, as they eliminate a lot of glue code. In places where they can't be used, your controllers (the middle layer in MVC) should use KVO to observe model changes and update the appropriate views. Changes in the views can be passed back to the model via property accessors and/or KVC by the controllers.
Yes, under normal conditions (or what I've usually seen), a class has
one delegate. But creating an array of delegates works as well (just
tested it).
Delegates are often used to modify the behavior of the delegating object. An application delegate is a good example: NSApplication by itself isn't very interesting; it relies on its delegate to define the interesting behavior of the application. Having multiple delegates all trying to modify the behavior of a single object could be a problem if the various delegates conflict with each other. What do you do if the delegates disagree?
There are some cases in Cocoa where a class uses more than one delegate, but each one has a separate role. For example, NSTableView has both a delegate and a data source, but both are really delegates of a sort.
The problem I see here is that every time I need to notify the
delegates I have to loop through them, make sure they respond to a
method, and call that method.
That's not hard to solve. For example, you could create an NSInvocation to encapsulate the call, and then send the invocation to each "delegate." However, if you do that you'll have nearly reinvented the notification system. If you need the one-to-many communication that you'd get with your multiple delegates proposal, you'll probably be better off using notifications or KVO.