Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C protocol circular dependency?

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

like image 904
Earl Grey Avatar asked Oct 09 '12 10:10

Earl Grey


People also ask

Can Objective c class implement Swift protocol?

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 .

How do you solve a circular dependency in Swift?

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).

What is circular reference IOS?

A circular reference is a series of references where the last object references the first, resulting in a closed loop.


1 Answers

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.

like image 138
justin Avatar answered Sep 21 '22 09:09

justin