For every object that can have a delegate, there is a corresponding protocol, that declares the messages that the object can send it's delegates. The delegate implements methods from the protocol for events it is interested in.
How can one view the protocol in order to find out what functionality needs to be implemented?
Protocols in Objective-C are non-essential, but they are useful; Protocols are usually declared in header (.h) files:
#protocol MyAwesomeProtocol
-(void)thisMethodIsRequired;
#optional
-(void)theseMethodsAreOptional;
#end
... and are usually used in a couple of places:
1: In an instance variable declaration:
#class Foo : Bar
{
id<MyAwesomeProtocol> someIvar;
}
#end
2: In property declarations:
#class Foo : Bar
{ }
#property (assign) id<MyAwesomeProtocol> someProperty;
#end
3: In code (Try to avoid this, but it's legal):
if(...)
{
[(id<MyAwesomeProtocol>)obj foo];
}
If you're using Xcode, you can always command-click a protocol that appears anywhere in your code to jump to the header where that protocol is defined. This is true even of Apple's protocols, since header files are not compiled. Also, the documentation available through Xcode provides additional insight on what methods are required or optional.
Since you can define optional protocol methods, you should always check to see if your delegate -respondsToSelector:#selector(isThisMethodImplemented:), since the language doesn't do this for you.
Also, if you're using Xcode, you can option-click a class in your code to bring up the quick documentation panel, which has an option to go to the full documentation for the class of the object you clicked on.
You can either look at the documentation or view the corresponding header file by Command-clicking the protocol in Xcode (Command-doubleclick in Xcode 3).
Check out the doc the delegate property, it is almost all the time defined is id type and which protocol it is conforming to : id <TheProtocolYouLookFor>.
If not, read down the description and you will find more information about the protocol. Protocol names are also links in general.
Related
In Java, C++11 and some other languages you can specify that a method is intended to override another method from a base class or interface, if you then at a later point remove the method from the base class you get a compiler error. I use protocols with optional methods a lot and find that if I remove a method from there I have a tendency to forget to remove the code that implemented the method. This does not generate an error or a warning, thus creating a "dead" method.
Consider:
#protocol Prot <NSObject>
#optional
- (void)bar;
- (void)tempBar;
#end
#interface MyType : NSObject <Prot>
#end
#implementation MyType
- (void)bar { /**/ }
- (void)tempBar { /**/ }
#end
If I at one point remove tempBar from the protocol, I would like to get at least a warning from tempBar being implemented in MyType.
Is there any way in Objective-C to specify that a method is expected to be an implementation of a protocol method?
Objective-C is a dynamic language and this is rather impossible to enforce at compile time. Note that in Obj-C you can actually call methods there are not even there and the app won't crash (well, the default implementation will raise an exception but you can change that behavior).
The method can be also added in an extension, or added at runtime. Or it is just not present in the header.
Note there is also the opposite problem. When subclassing, you can override a method which you don't even know is there, because it is not present in the headers.
This is one of the reasons why Apple is moving to a more predictable language, that is, Swift.
I am working in an app written in Objective-C and we would like to begin integrating some Swift into it.
I have written a simple view controller class in Swift and to work in the app it must conform to a protocol that was written in Objective-C. In my Swift class I have the following declaration:
#objc class SwfViewController: UIViewController, theProtocolName {
//some code
}
In my bridging header file I have the class name of the protocol referenced.
#import "theProtocolName.h"
I have implemented all of the required methods listed in the protocol, yet still I get an error saying
SwfViewController does not conform to protocol 'theProtocolName'
I'm fairly new to Swift and could have easily left out something. Any suggestions of what to check? Thanks!
You should take into account that Swift signature for methods is slightly different from objective-c. For example:
A protocol like this:
#protocol MyProtocol <NSObject>
- (void)didFinish:(MyClass *)class withError:(id)errorMessage;
#end
A class that conforms to this protocol in Swift should be:
#objc class SwfViewController: UIViewController, MyProtocol {
func didFinish(whatEveryouWant1: UIViewController!, withError whatEverYouWant2: AnyObject!){
}
}
Please note id becomes AnyObject and Obj-C references are translated with ! as implicitly unwrapped optionals.
Generally this error means that your class is missing required methods which is the part of the point of the protocol. The class seems to realize that it need to follow the protocol you've told it about, but now need to define the required pieces.
You should be able to expand the error message by clicking on it to find out which pieces are missing.
#import <UIKit/UIKit.h>
#protocol myProtocol <NSObject>
-(void)aMethod;
#end
#interface ViewController : UIViewController
#property (weak) id<myProtocol> dSource;
#end
I am trying to get a firm grip on Obj-c protocols, I am reading apple doc to study, few things are not clear to me. Below are the points from doc:
The pie chart view class interface would need a property to keep track of the data source object. (The code above, we mostly declare protocol this way, when I have protocol declared in my class why need a tracking object, Or protocol can be defined in independent class? and for that we need tracking object?)
By specifying the required protocol conformance on the property, you’ll get a compiler warning if you attempt to set the property to an object that doesn’t conform to the protocol.
If you attempt to call the respondsToSelector: method on an id conforming to the protocol as it’s defined above, you’ll get a compiler error that there’s no known instance method for it. Once you qualify an id with a protocol, all static type-checking comes back; you’ll get an error if you try to call any method that isn’t defined in the specified protocol. One way to avoid the compiler error is to set the custom protocol to adopt the NSObject protocol.
I dont understand this question
Correct, the property requires that the property is an id which
conforms to your property, if you try to set it to something else
the compiler rightly complains
This is because respondsToSelector: is a method on the NSObject
protocol, so you can either have your protocol extend NSObject
(standard), or you could declare the property as
NSObject
I am watching the Stanford University iPad and iPhone application Developments course video. The instructor says in the video we can control-drag an UI object to the implementation files to create an action. But in this way the method will not declare in the header file. Does this mean it is ok to implement methods in the .m file but not declare in the .h file?
Depends on how you define "ok" :-)
Objective-C uses dynamic method lookup and does not really enforce access ("private", "public", etc.) specifiers. So you don't need to declare any method in a header file.
However you will end up fighting the compiler as it does do a fair amount of type-checking unless you persuade it not to, and you'll lose by doing so.
You are not required to declare in the header file all methods in the implementation. But if not in the header file obviously you cannot reference them by literal name in another file, nor can you "forward reference" them in the implementation file.
(Note that this is not that different from regular C, but is different from methods of a class in C++.)
It's "OK" to not declare methods in the header yes, under certain circumstances. For instance, if using ARC then the compiler generally needs to know the method signature so it can do the right thing. But basically all it means is that wherever you're using the method, it must already know about the method you're calling.
Since you're talking about Interface Builder, that's slightly different in that it will know about all methods since it can "see" the whole context of your header and implementation files and know that a method exists. i.e. in my terminology above, the method has been defined before it's used.
With regard to defining before use, the general accepted approach is to either:
Define a method in the interface file (.h). e.g.:
MyClass.h
#interface MyClass : NSObject
- (void)someMethod;
#end
MyClass.m
#implementation MyClass
- (void)someMethod {
// do something
}
#end
Define a method in a class continuation category. e.g.:
MyClass.h
#interface MyClass : NSObject
#end
MyClass.m
#interface MyClass ()
- (void)someMethod;
#end
#implementation MyClass
- (void)someMethod {
// do something
}
#end
I've been working on a pet project for a few weeks now, and starting to think that it may get used by myself and a few friends. At present, it's really just a pile of Objective-C classes in an XCode project with a main() I've been using to test various features. Going forward it seems easiest to use this library in projects if I package it up as .dylib file. As I've found with other languages, doing this as an afterthought is a nuisance that ideally is farmed out to the lowest rung. :)
I'm very new to the Objective-C/Xcode world, but according to Apple's "Dynamic Library Programming Topics", I'm under the impression that it's really just a matter of rejigging my interface files to be of the format:
#protocol Person
- (void)setName:(NSString*)name;
- (NSString*)name;
#end
#interface Person : NSObject <Person> {
#private
NSString* _person_name;
}
#end
(taken from referenced Apple doc).
Where: I'm defining a protocol that contains the methods I wish to include for the classes to be contained in the .dylib, and then defining an interface that subclasses NSObject implementing the aforementioned protocol and declaring ivars in here.
A few questions:
Am I able to omit methods from the protocol that I don't wish to "EXPORT" to the dylib?
If I have subclasses of a class within the dylib, do I create another protocol for the subclass, and make the superclass of the newly created class implement that protocol? For instance, if I were subclassing person:
#protocol CatPerson
/* any additional methods for CatPerson not in Person */
- (void) protractClaws;
- (void) retractClaws;
#end
#interface CatPerson : Person <CatPerson> {
#private
/* any additional ivars for CatPerson not in Person */
NSNumber *clawCount;
}
It's likely a very trivial question, but I'm trying to figure out everything I'll need to do before I go thru the gnashing of teeth of moving all the classes to a .dylib.
Project->New Target… select "dylib" in the panel that you get. Make it the current target. control-click on the groups & files tableview header, check "target membership". Check the boxes next to the files you want included in your dylib.