Declare protocol conformance in objective-c protocol forward-declaration - objective-c

Assume a class has been defined like this in OriginalObject.h:
#protocol OriginalDelegate;
#interface OriginalObject : NSObject {}
#property (nullable, nonatomic, weak) id<OriginalDelegate> delegate;
#end
#protocol OriginalDelegate <NSObject>
// … delegate method declarations …
#end
Now, in ExtendedObject.h, I want to do this:
#import "OriginalObject.h"
#protocol ExtendedDelegate;
#interface ExtendedObject : OriginalObject {}
#property (nullable, nonatomic, weak) id<ExtendedDelegate> delegate;
#end
#protocol ExtendedDelegate <OriginalDelegate>
// … additional delegate method declarations …
#end
Attempting this gives me the following warning on the #property … delegate; line of ExtendedObject.h:
Property type 'id<ExtendedDelegate> _Nullable' is incompatible with type 'id<OriginalDelegate> _Nullable' inherited from 'OriginalObject'
It appears that the compiler doesn't know ExtendedDelegate will conform to OriginalDelegate. Moving the full protocol declaration above the ExtendedObject interface in ExtendedObject.h resolves the warning:
#import "OriginalObject.h"
#protocol ExtendedDelegate <OriginalDelegate>
// … additional delegate method declarations …
#end
#interface ExtendedObject : OriginalObject {}
#property (nullable, nonatomic, weak) id<ExtendedDelegate> delegate;
#end
What I'd like to know is… is there any way to tell the compiler in the forward-declaration that ExtendedDelegate will conform to OriginalDelegate (enabling use of something more like the first version of ExtendedObject.h above)?
Neither of the following attempts at such a forward-declaration seem to be valid syntax:
#protocol ExtendedDelegate <OriginalDelegate>;
#protocol ExtendedDelegate : OriginalDelegate;

Related

incompatible with type id<NSTextFieldDelegate>

I am getting new warning on my old OSX app. I am using OSX 10.10 and I am not quite sure where the problem is. Can someone help?
The actual warning is Property type 'id is incompatible with type id inherited from NSTextField
#import <Cocoa/Cocoa.h>
#import "HyperlinkTextFieldDelegate.h"
#interface HyperlinkTextField : NSTextField <NSTextFieldDelegate>
#property (assign) id <HyperlinkTextFieldDelegate> delegate; <--- warning showing up here
#end
The main implementation is
#interface HyperlinkTextField ()
#property (nonatomic, readonly) NSArray *hyperlinkInfos;
#property (nonatomic, readonly) NSTextView *textView;
- (void)_resetHyperlinkCursorRects;
#end
#define kHyperlinkInfoCharacterRangeKey #"range"
#define kHyperlinkInfoURLKey #"url"
#define kHyperlinkInfoRectKey #"rect"
#implementation HyperlinkTextField
#synthesize delegate;
And the delegate file is
#import <Foundation/Foundation.h>
#protocol HyperlinkTextFieldDelegate <NSObject>
- (void) barLinkClicked: (id) sender;
#end
NSTextField already has a delegate property, and it is typed as id<NSTextFieldDelegate>. Thus, your HyperinkTextField, which is a subclass of NSTextField, inherits this property, just as the error message clearly tells you. You cannot override this inherited property and type it as id<HyperlinkTextFieldDelegate> where that is a different type.

Forward declaration error

I have a protocol like this:
#import <Foundation/Foundation.h>
#protocol Prot1 <NSObject>
#required
- (void)methodInProtocol;
#end
This is a protocol for a delegate I want to store in a class like this:
#import <Cocoa/Cocoa.h>
#class Prot1;
#interface Class1 : NSObject
#property (nonatomic, strong) Prot1 *delegate;
- (void)methodInClass;
#end
The implementation for this class is like this:
#import "Class1.h"
#import "Prot1.h"
#implementation Class1
#synthesize delegate;
- (void)methodInClass {
[delegate methodInProt];
}
#end
When I build these pieces of code, I get the following error:
Receiver type 'Prot1' for instance message is a forward declaration
What is wrong here? I did understand that I have to do a forward declaration via #class for the protocol and I thought I only had to #import the protocol, in the class implementation... Isn't that right?
As it isnt a class, you have to define it as what it is - a protocol ;)
Use forward declaration: #protocol Prot1;;
And use the property like that:
#property (nonatomic, strong) id<Prot1> delegate;

How to properly subclass a delegate property in Objective-C?

In subclassing a class, I want to also subclass a delegate of the parent class given that the subclass now has additional functionality. What's the best way to go about doing this? If I just declare another delegate property in the subclass with the same name I would get a warning "Property type 'id' is incompatible with type 'id' inherited from 'ParentClass'
Given this example that produces the warning:
// Class A
#protocol ClassADelegete;
#interface ClassA : NSObject
#property (nonatomic, weak) id<ClassADelegete> delegate;
#end
#protocol ClassADelegete <NSObject>
- (void)classADidSomethingInteresting:(ClassA *)classA;
#end
// Class B
#protocol ClassBDelegete;
#interface ClassB : ClassA
#property (nonatomic, weak) id<ClassBDelegete> delegate; // Warning here
#end
#protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
#end
Two solutions that remove the warning are.
1) In the subclass, place the protocol definition before the class definition. This is what UITableViewDelegate in UITableView.h does:
// Class B
#class ClassB;
#protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
#end
#interface ClassB : ClassA
#property (nonatomic, weak) id<ClassBDelegete> delegate;
#end
2) In the subclass, add the original protocol alongside the new one:
// Class B
#protocol ClassBDelegete;
#interface ClassB : ClassA
#property (nonatomic, weak) id<ClassADelegete, ClassBDelegete> delegate;
#end
#protocol ClassBDelegete <ClassADelegete>
- (void)classBDidSomethingElse:(ClassB *)classB;
#end
I assume (1) works as Apple do it this way, Option (2) removes the warning but I haven't compiled and run anything setup this way.
Follow the example of NSTableView and NSOutlineView.
NSOutlineView is a subclass of NSTableView, and defines its own protocol for its dataSource and delegate.
NSTableView declares its delegate this way:
- (void)setDelegate:(id <NSTableViewDelegate>)delegate;
- (id <NSTableViewDelegate>)delegate;
and NSOutlineView:
- (void)setDelegate:(id <NSOutlineViewDelegate>)anObject;
- (id <NSOutlineViewDelegate>)delegate;
Apparently the compiler is more lenient with bare method declarations than it is with property declarations.
Unlike NSTable/OutlineView, you might want to make the subclass's protocol inherit from the base class's protocol, e.g.
#protocol SpecializedProtocol <BaseProtocol>
... it probably depends on the situation.

Expected ')' before error in objective-c protocol declaration

In WebServiceAPI.h, which I referred in the code below, i declared a protocol with a required metod -(void) apiFinished:(WebServiceAPI *)api. When compiling the code i get this error: WebServiceAPI.h:13: error: expected ')' before 'WebServiceAPI' (line 13 is where the method of the protocol is declared). where am I doing wrong?
#import <Foundation/Foundation.h>
#protocol WebServiceAPIDelegate
#required
-(void) apiFinished:(WebServiceAPI *)api;
#end
#interface WebServiceAPI : NSObject{
NSString *address;
NSMutableData *dataWebService;
}
#property (nonatomic, assign) id <WebServiceAPIDelegate>delegate;
#property(nonatomic, retain) NSString *address;
#property(nonatomic, retain) NSMutableData *dataWebService;
#end
The problem is that WebServiceAPIDelegate doesn't know about the class WebServiceAPI when it is defined. Add a #class directive before you create WebServiceAPIDelegate #protocol declaration.
// Add the following line to let the compiler stop worrying about
// the existance of class WebServiceAPI
#class WebServiceAPI;
#protocol WebServiceAPIDelegate
#required
-(void) apiFinished:(WebServiceAPI *)api;
#end

Substituting classes that adopt a particular protocol (Objective-c)

In Objective-c if two classes adopt a particular protocol can instances of the classes be used interchangeably?
Say I have the following code:
#protocol MyProtocol
#required
#property (nonatomic, retain) SomeObject *object;
#end
#interface ClassA <MyProtocol>
#property (nonatomic, retain) SomeObject *object;
// ...
#end
#interface ClassB <MyProtocol>
#property (nonatomic, retain) SomeObject *object;
// ...
#end
Can I substitute (id <MyProtocol>)instanceOfClassB when a method expects an instance of ClassA ?
Nope. Instances of different classes that conform to the same protocol can be used interchangeably when the API is explicitly typed that way though, e.g.:
- (void)someMethod:(id <MyProtocol>)someObj;