I have a protocolA in its own header file, that serves as an interface. Then I have two concrete classes that are different implementations of that protocol.
Now, in my ViewController, I use this for declaring a property of type id , and it allows me to swap implementations without VC knowing anything about this.
I also have protocolB, that serves for delegate calls from those two implementation objects to the VC.
The problem is I have circular dependency.
In protocol A, i need to declare a "delegate" property of type id. In protocol B, the delegate methods are sending reference to the caller which is an object of type id...
Is there a better design?
UPDATE with example, maybe it will be helpful for others.
ProtocolA header:
#import <Foundation/Foundation.h>
/*!
Abstract interface for any Provider
*/
@protocol DataProviderDatasource <NSObject>
@required
@property (nonatomic) id <DataProviderDelegate> delegate;
-(void)update;
@end
ProtocolB header
#import <Foundation/Foundation.h>
#import "DataProviderDatasource.h"
/*!
Protocol that each Data Provider implements to make delegate calls to notify its delegate about data management operations.
*/
@protocol DataProviderDelegate <NSObject>
-(void)dataProviderWillUpdate:(id<DataProviderDatasource>)dataProvider;
-(void)dataProviderdidUpdate:(id<DataProviderDatasource>)dataProvider;
@end
In order to use Swift code inside Objective-C one must scrifice some Swift features and write a wrapper around original Swift code that won't use non-compatible features (like structs, generics, enum associated values, protocol extensions etc.). All wrapper classes must inherit NSObject .
It's simply not possible. You need to change at least one of the classes to have an initializer that does not need the other. Then you also have a problem of both having a strong reference to the other. This will cause a reference cycle (a form of memory leak).
A circular reference is a series of references where the last object references the first, resulting in a closed loop.
like classes, you can forward declare protocols:
@protocol MONProtocolB; // << forward declaration -- #import not required
@protocol MONProtocolA
- (void)setDensity:(NSValue<MONProtocolB>*)pValue;
^^^^^^^^^^^^ << compiler recognizes this as an
objc protocol
@end
then the compiler won't barf when it sees the protocol name and circular dependence is broken (unless your protocols both derive from another which is of course silly).
you can then #import
MONProtocolB wherever there is physical dependence.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With