Delegate Syntax - ios

If I create a tableview in interface builder and connect the datasource and delegate to files owner there, do I also need to do this in the implementation of said viewcontroller?
#interface myViewController : UIViewController **<UITableViewDataSource**, **UITabBarControllerDelegate>**
ie manually specify protocol adherence?
Thanks,

When setting the delegate and datasource from interface builder there seems to be no reason to specify what protocols that class conforms to.
It works without manually specifying them because the language is pretty dynamic and this process of calling the delegate methods is done at runtime without being sure if the object does or doesn't have the required methods.
Only when setting the delegate/datasource from code there is some static type checking to see if the delegate/datasource conforms to the needed protocols.
Bottom line: write them. You get xcode autocompletion, maybe some warning in some cases, code documentation and some OCD fulfillment.

Yes. Specifying in the code that the class implements the protocols is what tells the XIB that you can make the connections and tells the compiler that all of the required methods from the protocols must be implemented (and a warning should be raised if they aren't).
Technically you can do without them, but you shouldn't.

Did you try it? Did it work without?
You're only able to connect them in interfacebuilder when you add the UITableViewDataSource and UITabBarControllerDelegate in your header file.
Just don't forget to implement the required methods (datasource & delegate) in you implementation. You'll get a warning when you do forget them btw.

Related

How the UITableViewDelegate and UITableViewDataSource methods get automatically called?

Just conforming to the datasource and delegate protocol and assigning the delegate and data source object in my class implementation file and defining the methods defined under the datasource and delegate protocol is all anyone need?How does those methods get called automatically?
It's just a kind of design pattern, which expose to you as many methods as needed to give you enough flexibility to control it and hide from you all the hard work.
Since you're assigning self to delegate and datasource properties, that mechanism is just calling those exposed protocol method on object which is the "self". Those methods are called while it's building up dynamic content, while reloading, etc.
If you're interested with implementation, you could check this open class with the same design pattern:
iCarousel

Why a delegate work also without defining it in the interface file?

I have a simple question to ask.
I have a ViewController that use a UITableView to show a list of things. The UITableView delegates are the this ViewController (using dataSource = self, etc..)
In all tutorials i know that i need to define the delegate class in the interface using:
#interface Class : SuperClass <ClassNameDelegate>
But all the code works good also without declaring this and implementing only the methods. For example:
#interface Class: SuperClass
Is a bug? I need to declare it anyways?
Thank you.
Mauro
In common case we use performSelector to call delegate methods like this:
[(NSObject *)_delegate performSelector:#selector(storeFeedbackViewControllerWasDismissed)];
and everything works because this delegate have got this method.
But it's better to point that class conforms protocol because XCode can warn you to implement required delegate methods that you can miss.
There is three moments:
Yours second class will return NO for call conformsToProtocol:#protocol(ClassNameDelegate)
If ClassNameDelegate have required methods, you will not get compilation second class error if it's not implement requited methods.
You will get warning if try assign object of second class to id<ClassNameDelegate>

How to make all subclasses necessarily conform to protocol?

I have a base class SLBaseViewController which is a subclass of UIViewController and want all its subclasses to conform to protocol:
#protocol SLLocalizable <NSObject>
- (void)localize;
#end
The problem is that I don't need SLBaseViewController to conform to protocol itself, but I need compiler to warn me if a subclass doesn't conform.
What I have tried:
Define base class like this:
#interface SLBaseViewController : UIViewController <SLLocalizable>
In this case compiler tells me that SLBaseViewController does not implement localize method.
Make localize optional.
Compiler keeps silence. But that's not what I need.
Make each of subclasses conform to protocol itself. That seems to be a right way, but I have more than 50 subclasses and it's a long way.
Is there a simple way to reach my goal?
You can't specify that the subclasses implement any protocol other than to specify it in the subclass itself.
Search for the subclasses to edit them (rather than trying to remember each). A reflex search would be able to find subclasses which don't give the protocol name.
As a safety check, make the superclass throw an exception if it's called so you know when you missed something. Obviously this only works during testing.
If this makes you paranoid, you could try writing a unit test which gets all the subclasses and calls localize on them.
In what case would you need all subclasses to implement something, but don't need the common superclass to implement it?
If it is that SLBaseViewController is an abstract class that is not meant to be instantiated directly, you can simply have it implement -localize, and in the body throw an exception. Or, you can simply ignore the warning (it is just a warning after all).

Delegate ivar explanation

What exactly does this line do:
id <ViewControllerDelegate> delegate
It's always declared as an instance variable in the viewcontroller that implements the delegate protocol, don't understand what it does though.
Thanks
It means delegate is an object which implements ViewControllerDelegate protocol methods. It helps the compiler to know the methods delegate is supposed to implement.
It's useful for checking type safety at compilation time and helps with autocompletion too.
It means that any methods or properties declared in the protocol can also be handled in the delegate. Typically setting a delegate would mean that those delegate methods are called by any instances that conform to the protocol.
A table view, for example, requires you to implement a delegate, typically on 'self'. Doing so means you inherit those properties and / or methods provided in that protocol. This is how you get those magical, - (UITableView *)table... methods. That's the basic idea of it.
Also, you can take a look at this answer. Hope that helps!

Is it necessary to declare an object as a delegate to use it as such?

I made a NSURLConnection with the calling class as the delegate.
I built this on to my test device before realizing I never declared the object as observing the protocol, but it ran (I would say normally, but I think I totally screwed my app around multiple threads).
So is it not necessary to declare an object as implementing a delegate?
I also did not include all the required delegate methods, and it still called the delegate methods.
There are other people on this project, and its fairly large so maybe the delegate protocol is declared somewhere obscure, but I didn't see it while searching for it in the header and implementation declarations.
The delegate parameter of the NSURLConnection initWithRequest:delegate: method is defined with a type of id<NSURLConnectionDelegate>.
If you pass an object that does not declare that it conforms to the NSURLConnectionDelegate, you should get a compiler warning indicating that you are passing the wrong kind of object. Double check to see if you get any sort of warning. If not, then somewhere your class properly declares it conforms to the protocol.
At runtime, the only requirement is that the delegate object actually implements at least the required methods of the delegate. But in this case there are no required methods in the protocol. They are all optional.
You state: "I also did not include all the required delegate methods, and it still called the delegate methods." This doesn't make sense. How can they be called if you don't implement them? Plus, there are no required methods in the protocol.
I think it depends on how NSURLConnection is implemented. First, if the setDelegate: method/property is set to accept an object of type id<NSURLConnectionDelegate>, then the compiler should warn you. If the NSURLConnection source code checks the delegate with (for example) +conformsToProtocol: before calling any protocol methods on it, then your object shouldn't be called back.
EDIT: rmaddy adds that all methods in the protocol are optional. Being that the case, then NSURLConnection most likely checks with (instance)-respondsToSelector: instead of (class)+conformsToProtocol:. In which case, having implemented the method should be enough (but you should still get warnings on -setDelegate:)
Despite what the documentation says, if you look at Cocoa's actual definitions of initWithRequest and connectionWithRequest, they are defined as follows:
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate;
+ (NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(id)delegate;
As you'll see, the delegate parameter is defined as id without any explicit, formal protocol specified, and as such, you won't get an warning if the object you pass to it doesn't happen to be defined as conforming to any particular protocol.
So, in answer to your question, in this particular case, you don't have to define the delegate to conform to any particular protocol. In many other cases, the delegate property is defined to take a pointer that conforms to the appropriate protocol, so the compiler will warn you if your object doesn't conform. But not in this case.
Needless to say, you probably should go ahead and define to which protocols you're conforming because it makes you code more clear and you'll enjoy, at the very least, better auto-completion in Xcode when you start to write one of these methods. But your question wasn't whether you should (which you should), but rather whether you must (which you don't).
And just as a clarification, in iOS, there are now two NSURLConnection protocols, NSURLConnectionDataDelegate and NSURLConnectionDelegate. (This may be why they don't define the protocol in the method declarations, to avoid confusion with their shifting of some methods into this NSURLConnectionDataDelegate protocol.)

Resources