Need assistance understanding objective-c protocol - objective-c

#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

Related

Explaning syntax for #property id<delegateName>

I see a lot of code references when writing delegates using something likes
#property (nonatomic, weak) id<mySuperCoolDelegate> delegate;
normally where id<mySuperCoolDelegate> is, is the data type of the property. So the questions are:
Is my understanding correct, that above syntax is telling the compiler data type of the id is mySuperCoolDelegate?
Any other examples where this sort of code (data type specified for id) could be used?
Thanks!
This piece of code is objective-c's way of implementing interfaces (as in Java or Go). using "id" means that you don't know at compile time what type of object it will be. But using the protocol in angle brackets you are telling the compiler that no matter what object it will be, it will need to support the 'mySuperCoolDelegate" protocol. If it doesn't - the compiler will let you know.
This syntax tells the compiler that delegate is of some kind of class (any class) that implements the mySuperCoolDelegate protocol.
This allows a certain component to notify another component on some event that happened without the need to know about the notified component (type-wise). (e.g. UITextView notifies its controller that the text has been changed without having a reference to that controller, only through the generic-typed delegate so the UITextView does not need to limit itself to a specific controller's type)
Also note that delegates are usually declared as weak (rather than strong). If an instance of UIViewController has a strong reference to a UITextView instance and that text view delegate (assume it is strong) is the controller instance then you will have a retaining cycle where both objects release will be dependent on the other object's release (which will never happen and leave you with a memory leak).
Short:
This tells the compiler that the property can be of any type as long as it implements the protocol mySuperCoolDelegate.
Still too short to be 100% accurate but easy to understand:
id is similar to NSObject*, meaning it is a reference to any kind of object (not only subclasses of NSObject, to be frank). Witin <> you declare which protocols the object has to conform to.
Example: It could be both:
#interface mySuperCoolClass : <mySuperCoolDelegate> ... #end
or
#interface somebodyElsesSuperCoolClass : <mySuperCoolDelegate> ... #end
Wherever you use that property, the compiler will allow you to access all methods that are declared in the related #protocol (most likely in some .h file that you need to #include).

Objective-C protocol as parameter in another protocol

I am trying to create a generic repository (pattern) that accesses my web api. I am having trouble understanding how protocols work in objective-c (I come from c# where interfaces are a bit different).
What I am trying to do is have ProtocolA be a parameter in another ProtocolB and then in the implementation of ProtocolB access methods on ProtocolA, since the object passed in to ProtocolB must implement ProtocolA itself. Am I thinking about that correctly?
This is what I have thus far, but can't seem to get it to work - maybe my logic is wrong:
//PGenericModel.h
#protocol PGenericModel <NSObject>
- (void)testMethod;
#end
//PGenericRepository.h
#import "PGenericModel.h"
#protocol PGenericRepository <NSObject>
#required
- (void)Get:(id<PGenericModel>*)entity;
#end
//GenericRepository.m
#import "GenericRepository.h"
#implementation GenericRepository
- (void)Get:(id<PGenericModel>*)entity
{
//GET
[entity testMethod] <-- this doesn't work...
}
#end
It is not working because an id type is already a pointer to an Objective-c object.
So you should declare the signature as
- (void)Get:(id<PGenericModel>)entity
not id<PGenericModel>*, otherwise the argument would be a pointer to a pointer to an Objective-C object, you can't send messages to it unless you get the concrete value.

Is Delegators really Categories in Objective-C?

I'm trying to understand the Informal protocols, until now I know that Informal protocols are a kind of Category, but, why delegators don't have a category name?
Example:
#import <Cocoa/Cocoa.h>
#class FileSystemNode;
#interface AppController : NSObject { // Where is the Category ????
#private
IBOutlet NSBrowser *_browser;
FileSystemNode *_rootNode;
}
#end
Thanks.
Informal protocols are not "a kind of category".
If a class conforms to a protocol (for example #interface MyClass <MyProtocol>) it is guaranteed that you can call all methods on that class that are required by MyProtocol. (Unless the class doesn't really implement them [the linker can't know that because of dynamic binding], which is a programming error and a lie, but that is usually not the case.)
Categories on the other hand allow you to take an already existing class and extend it with new methods (for example adding a removeAllSubviews method to the already existing NSView class).
So, categories and protocols are quite the opposite of each other.

Objective-C: How to view a protocol?

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.

How to override a superclass' property with more specific types?

The Scenario
I have a situation where a base class called AbstractRequest has a delegate property of type id <AbstractRequestDelegate> declared in the header file:
#property (nonatomic, assign) id <AbstractRequestDelegate> delegate;
The abstract delegate protocol contains a few required methods, and as indicated with the word 'abstract', both the AbstractRequest and the AbstractRequestDelegate are intended to be subclasses/extended.
One example of this would be the subclass ConcreteRequest and extended protocol ConcreteRequestDelegates, that both add extra methods to the abstract ones. The intention is that both the abstract and concrete class methods can send messages to the single assigned delegate instance.
At a certain point in time the ConcreteRequest would like to call a method on the delegate that is defined by ConcreteRequestDelegate. Because the type of the delegate is id , the compiler will give a warning that this method might not be implemented.
ConcreteRequest.m:38: warning:
property 'delegate' requires method
'-delegate' to be defined - use
#synthesize, #dynamic or provide a
method implementation
The Problem
This warning is justified, for the property is after all typed to id <AbstractRequestDelegate>. In order to fix this, I want to make clear to the compiler that the delegate assigned to the concrete instance must be of type id <ConcreteRequestDelegate>. This sounded perfectly reasonable to me, so I put in a new property in the ConcreteRequest header, hoping to override the abstract one:
#property (nonatomic, assign) id <ConcreteRequestDelegate> delegate;
But this is where the compiler disagrees with me, probably with good reason. I would have thought it would give a warning for overriding a super class' property with the wrong type, but instead it just demands me to re-synthesize this new property. I don't want to go there, because then the super class' methods won't have access to the same delegate property.
The Question
Is there a way to 're-declare' the property in the concrete subclass with the added type information? Or can you spot the error in my thinking, for maybe this is a fairly common problem that I just haven't come across until now?
Cheers,
EP.
P.S. All class and protocol names appearing in this work are fictitious. Any resemblance to real class and protocol names, open source or patented, is purely coincidental.
The warning already gave the right clue. I used #dynamic in the overriding subclass and all is good.
Just synthesize id<ConcreteRequestDelegate>delegate in the ConcreteRequest.m it will work fine...It won't create any problem.