shebelaw
shebelaw

Reputation: 4162

Forward Class and Protocols in Objective C

I have two classes where both of them have protocols to be implemented.

Can I implement one of the class's protocol in to the other and vice versa?

Does this cause any run time error?

Upvotes: 3

Views: 252

Answers (2)

Sandeep
Sandeep

Reputation: 21144

But, I dont suppose this is really necessary. Once you have a delegate implemented then you could send a message to the other class as it the same delegate object. I suppose a simple delegate relations as;

Class A

@protocol ClassAProtocol;
@interface ClassA:NSObject
@property(nonatomic, assign) id<ClassAProtocol> delegate;
@end
@protocol ClassAProtocol <NSObject>
-(void)classA:(ClassA*)classa didSomething:(id)object;
@end

@implementation ClassA
-(void)classAFinishedSomething{
    [self.delegate classA:self didSomething:nil];
    [(ClassB*)self.delegate doSomething];
}

@end

Class B

@interface ClassB : NSObject<ClassAProtocol>
-(void)doSomething;
@end
@implementation ClassB
-(void)doSomething{

} 
-(void)classA:(ClassA*)classa didSomething:(id)object{

}
@end

This will not create a circular reference between the two objects and keep the code clean I suppose. This logic is valid if the delegate is always class B and it respondsToSelector:, the one being sent as a message to class B. But, the above sample posted by matt is mode rigid if you want to have isolate the log between the classes and communicate via standard mechanism.

Upvotes: 0

mattjgalloway
mattjgalloway

Reputation: 34912

Your problem is cyclic dependencies. Forward declaring won't really help either as you'll just get the compiler warning you that it can't see the definitions of the protocols. There are two options:

Option 1

Split the protocols out into their own header files:

ClassA.h:

#import <Foundation/Foundation.h>
#import "ClassBProtocol.h"

@interface ClassA : NSObject <ClassBProtocol>
@end

ClassB.h:

#import <Foundation/Foundation.h>
#import "ClassAProtocol.h"

@interface ClassB : NSObject <ClassAProtocol>
@end

ClassAProtocol.h:

#import <Foundation/Foundation.h>

@protocol ClassAProtocol <NSObject>
...
@end

ClassBProtocol.h:

#import <Foundation/Foundation.h>

@protocol ClassBProtocol <NSObject>
...
@end

Option 2

If you don't care about declaring externally that you implement the protocols, then you could use the class continuation category:

ClassA.h:

#import <Foundation/Foundation.h>

@interface ClassA : NSObject
@end

ClassA.m:

#import "ClassA.h"
#import "ClassB.h"

@implementation ClassA () <ClassBProtocol>
@end

@implementation ClassA
@end

ClassB.h:

#import <Foundation/Foundation.h>

@interface ClassB : NSObject
@end

ClassB.m:

#import "ClassB.h"
#import "ClassA.h"

@implementation ClassB () <ClassAProtocol>
@end

@implementation ClassB
@end

Upvotes: 3

Related Questions