I was checking some video at Lynda.com about iphone development.
The guy was adding custom data to a picker, but to add the data he was not declaring the methods in the header file. He was checking which nethods he needed on the documentation and copying pasting those methods declarations in his controller class.
For exampe this method
-(int) numberOfComponentsInPickerView: (UIPickerView *) pickerView
Why doesn't we need to declare those methods on the header file?
If those methods pertain to the picker class, why do we declare them in the controller class instead of simply calling them in the picker IBOutlet instance?
TIA
When you declare in your header that you follow a certain protocol, you are essentially saying that you agree to implement the methods defined in the protocol.
I'll bet he added something like this to the header:
<UIPickerViewDataSource>
That means that he is implementing the UIPickerViewDataSource protocol.
So, by implementing the UIPickerViewDataSource protocol, you are implying those methods, therefore, they do not need to be prototyped.
If those methods pertain to the picker class, why do we declare them in the controller class instead of simply calling them in the picker IBOutlet instance?
The method you quoted does not belong to the UIPickerView class, but rather to the UIPickerViewDataSource protocol. Your controller acts as a "helper" for the picker, so the picker is calling your controller if it needs to figure out how many components it should display. You are usually not calling this method yourself.
As another answer pointed out, by declaring that you implement the protocol, the methods of that protocol are implicitly declared. By adding <UIPickerViewDataSource> to your interface, you're basically saying "I can act as a data source for a picker view and I'm ready for any picker that wants to call the methods that are declared in the protocol".
Related
I've seen several Obj-C tutorials. The delegate classes all inherit from NSObject. For example, the applicationDidFinishLaunching delegate method, in some tutorials, it inherited from NSObject but NSApplication to implement it. The reason I don't think it should inherited from NSObject is that I didn't find any delegate protocol declaration in it, but I found that delegate protocol declaration in NSApplication. My Objective-C toy environment is GnuSep.
Here is some code:
#interface browserController : NSObject //here. inheriting from NSObject,but NSObject don'have any protocols declaration about applicationDidFinishLaunching.
{
NSBrowser *browser;
}
#end
#implementation browserController
- (void)menuAction:menuItem
{
..............................
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSWindow *win;
ActiveBrowserDelegate * abd;
WindowDelegate *wd;
NSRect wf = {{100, 100}, {600, 500}};
NSRect bf = {{10, 10}, {580, 350}};
.............................
}
It is called informal protocol (though GNUstep declared it anyway as GSAppDelegateProtocol for documentation purpose) NSApplication will simply check it at runtime if your delegate object will respond to the message, (using -respondsToSelector:) A delegate can be a view, a string, a proxy, anything as long as you make it responds to the selector. You don't need to make your delegate implement every method in such protocol since all verifications would be done at runtime. To make it looks cleaner you could just redeclare -applicationDidFinishLaunching: in #interface though you don't really need to, just make one in the #implementaiton is enough.
A delegate may inherit from anything appropriate. It is usually supposed to implement a certain protocol.
A protocol is a way of implementing a formal communication interface between two classes.
However, it is most unlikly that a delegate will inherit from its communication partner class.
With other words: Protocols are often used to overcome the unavailability of multiple inheritance. (Pretty much like interfaces in Java)
Example: A UIViewController subclass' instance controls a view that contains a UITableView. Rather than subclassing the UITableView for the implementation of its look or data, there are two delegates assigned to the table view object. One delegate serves as provider for custom layout (provides items such as the header view) and another (?) delegate provides the data that is being displayed.
Now, this delegate could be any object, inheriting from NSObject and implementing the two protocols. This object cold then be instanciated by the view controller and assigned to the table.
However, it is common practice that the view controller itself serves as delgate for the table(s) that it controls. That is a good pattern but strictly spoken not required. It could be any object.
Now the custom view contoller inherits from UITableViewController (which already implements the protocols and inherits from ViewController) and serves as delgate for the table view. The table view itself could be any subclass of UITableView. (Although this is a bad example here because subclassing UITableView is normally not advisable)
If the delegate does not need to inherit from any class and just implements the protocol, then it shold at least inherit from the cocoa base class NSObject. That ensures that it inherits all the usual capabilites and behaviour of any object. (init method, copy method, description method etc.) That may be required to work properly with other classes of the framework such as beeing used as an object within an NSArray, NSLog etc.
I am learning to program a simple Web Browser Mac App in Objective C. I have a simple textfield as an address bar and a Webview. As such, I wish to update the address the website in the textfield whenever the page changes when I click a link.
After googling, I realise I could use a method
didStartProvisionalLoadForFrame
in the WebFrameLoadDelegate Protocol. I then proceed to type
#interface AppDelegate : NSObject <NSApplicationDelegate,WebFrameLoadDelegate>
which resulted in an error. After further search I found out that is due to WebFrameLoadDelegate being an informal Protocol.
My question is then this: What is the syntax for using the method below specified by the informal Protocol?
- (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame*)frame;
With an informal protocol, you implement the methods without declaring conformation to a protocol. WebFrameLoadDelegate is not a type, just the name of an NSObjectcategory.
They exist because, previously, there was no way to specify that a method in a protocol was optional (the #optional and #required keywords did not exist.) When the requisite keywords were added to Objective-C, Apple started moving to formal protocols with optional methods, which makes for better type safety and self-documenting code.
If you're manually creating a webview, then just set your own class as the delegate as following [webview setDelegate:self]. But if you made the webview in IB instead, you can link the delegate there instead.
Once you set your class as the delegate of the webview, you can just implement that method without any extra code.
- (void)webView:(WebView *)webView didFinishLoadForFrame:(WebFrame*)frame
{
//Do stuff here.
}
And the WebView will simply call your method whenever it finishes loading a frame.
If you want to know how this works, it all goes back to the construction of a delegate. WebView will check if delegate is nil or not. If it's not, then it will call respondsToSelector: to check if the delegate has implemented the delegate method. An informal delegate is just an old way of allowing optional protocol method, which shouldn't be used anymore as stated by #JonathanGrynspan
And if you didn't know, you don't have to explicitly declare that your class confirms to a protocol (even if it's not informal) if you connect it in IB.
By the way, if you're working on a webview, check out Apple's development guide on it. It gives you a step-by-step tutorial on creating the basics of a webview including when to change the webview's URL address.
I need to call a method and pass an object from my custom UITableViewClass implementation to my UITableViewController class. I realize creating an instance of the tableViewController in the custom tableViewCell and calling tableViewController's method is a bad practice.
What is the proper way of doing this?
Two magical concepts in Objective-C are Delegation and Notifications.
Delegation allows you to have your controller hook into a weak object referenced in the cell, which avoids a retain cycle, while still allowing you to send messages to it.
Notifications allow your Cell to broadcast a general notification to any classes that are active and listening for it.
Pick one, and whichever is easiest, stick with it. The two are basically equal in this situation.
Having a reference of the tableController inside the cell is indeed Bad practice
You could fix this by implementing a special #protocol for your UITableViewClass
And add a delegate method to it, and then implment the method inside UITableViewController, and since your UITableViewClass delegate is your UITableViewController, then you would call it like
in your UITableViewClass.m
[delegate someMethod:data];
I need all my view controllers to be able to show the Message compose view controller (MFMessageComposeViewController) and also handle MFMessageComposeViewControllerDelegate method to see whether a message was sent/cancelled/failed. So my idea was to subclass UIViewController impement these methods in this view controller. And then have all my view controllers that need to be able to send messages subclass the above view controller.
So like BaseMessageViewController : UIViewController
And then ViewController1 : BaseMessageViewController, ViewController2 : BaseMessageViewController and so on...
So when I was at it, I thought I would create a protocol like this:
#protocol MessageProcessing
#required
- (void)presentMessageCompose;
- (void)processMessageCancelled;
- (void)processMessageSent;
- (void)processMessageFailed;
#end
But I'm not sure if BaseMessageViewController should conform to this protocol or if my "concrete" view controllers should conform to it?
One thought was that if my BaseMessageViewController conforms to it then my concrete view controllers would automatically conform to it because of class inheritance? But I'm not seeing any warnings in my concrete view controllers that they are not implementing a required method.
Can someone please give me a helping hand here :)
If these are messages that BaseMessageViewController sends to self, there's no reason to define a protocol. Just declare the methods in BaseMessageViewController, and comment the declarations to describe when they are sent.
You will also need to provide implementations of the methods in BaseMessageViewController to suppress a compiler warning. If you want every subclass to implement the methods, you can define the methods in BaseMessageViewController using this pattern:
- (void)processMessageCancelled {
[self doesNotRecognizeSelector:_cmd];
abort();
}
This is a classic example of the Abstract Base Class vs protocol question.
Use an Abstract Base Class (in Cocoa these are called Class Clusters) when you'd like to define a framework, with some common concerns encapsulated by the framework and some specific concerns to be handled by sub-classes. An example could be a message parsing framework.
Use a Protocol to define a common contract for classes that need their own object hierarchy. An example might be a media player, where 'play' and 'stop' are completely different depending on the type of media.
Alternatively, for something in-between, Justin Spahr-summers defines the 'concrete protocol' in libextobjc. . . https://github.com/jspahrsummers/libextobjc (similar to concrete interfaces in Java 8).
I have a class 'EditingField' extending the NSTextField. The textfields are variables in my AppDelegate.
I wish to do something after the user has ended editing the textfield. Apparently i am to use the controlTextDidEndEditing or textFieldDidEndEditing. Which one am i to use?
Furthermore where exactly am i to implement the methods and how do i set a delegate if that is required?
If you're using NSTextField (i.e. are developing for OS X) then you'd use controlTextDidEndEditing. If you're using UITextField (i.e. are developing for iOS) then you'd be using textFieldDidEndEditing.
The delegate methods can be implemented in any class you wish, in a very small application perhaps even in the app delegate, otherwise you'd probably implement them in the controller responsible for the part of the UI containing the text field.
To set a delegate, use the setDelegate: method.