Objective-C: risolvere i warning Semantic Issue: Receiver XXX is a forward class and corresponding @interface may not exist

Posted: giugno 7, 2011 by eamedeo in Uncategorized
Etichette: , , , ,

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.

Lascia un Commento

Fill in your details below or click an icon to log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Log Out / Modifica )

Foto Twitter

You are commenting using your Twitter account. Log Out / Modifica )

Foto di Facebook

You are commenting using your Facebook account. Log Out / Modifica )

Connecting to %s