A pagina 123 di Objective-C Pocket viene spiegato come risolvere i problemi circolari tra le classi (con i delegati si può presentare un problema simile, se ne fa cenno a pagina 174). In parole povere, un problema circolare si ha quando la classe A fa riferimento alla classe B e viceversa. Non è possibile includere, in ciascun file d’intestazione, il file d’intestazione dell’altra classe, perché il compilatore va in confusione. Cioè, non è possibile scrivere:
//
// ClasseA.h
//
#import "ClasseB.h"
@interface ClasseA : NSObject {
}
@end
e:
//
// ClasseB.h
//
#import "ClasseA.h"
@interface ClasseB : NSObject {
@end
Per ovviare a questo problema è possibile utilizzare la direttiva @class nel file d’intestazione, per specificare che i simboli ClasseA e ClasseB fanno riferimento alle classi.
Fino a qui tutto bene, ma quando si utilizzano effettivamente le classi dichiarate con @class nel codice dell’implementazione viene sollevato il warning in oggetto. Per esempio:
//
// ClasseA.h
//
@class ClasseB;
@interface ClasseA : NSObject {
@private
ClasseB *objB;
}
@end
//
// ClasseA.m
//
#import "ClasseA.h"
@implementation ClasseA
- (id)init
{
self = [super init];
if (self) {
objB = [[ClasseB alloc] init];
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
@end
In questo caso sulla riga dove viene allocato un oggetto di tipo ClasseB viene presentato il warning seguente:
warning: Semantic Issue: Receiver ‘ClasseB’ is a forward class and corresponding @interface may not exist
Questo perché se è vero che non bisogna includere il file d’intestazione di ClassB in quello di ClassA, questo è comunque necessario all’implementazione di ClassA. Per risolvere il problema è bisogna quindi includere ClassB.h nel file ClassA.m, che quindi diventa:
//
// ClasseA.m
// RiferimentiCircolari
//
#import "ClasseA.h"
#import "ClasseB.h"
@implementation ClasseA
- (id)init
{
self = [super init];
if (self) {
objB = [[ClasseB alloc] init];
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
@end
Ricompilando il progetto si noterà che il warning non viene più presentato.