Domanda

Quando ho provato a compilare la mia app per OS 3 ho riscontrato il seguente errore:

errore: il tipo di accesso non corrisponde al tipo di proprietà

L'errore era per una proprietà a cui ho provato ad accedere che è definita come segue:

NSMutableArray *myArray

@property (readonly,nonatomic) NSArray* myArray;

la proprietà è @synthesized nel file di implementazione.

Funzionava perfettamente con OS 2.2.1 ma non è OS 3.0

Scrivere io stesso il metodo getter ha risolto il problema.

Qualcuno è a conoscenza delle modifiche all'obiettivo-c tra OS 2.2.1 e 3.0? Esiste una documentazione per queste modifiche?

L'API documento modifiche non sembra contenere nulla su questo problema.

MODIFICA

l'errore si verifica quando si tenta di accedere alla proprietà, ad es.

NSArray *anArray = myClass.myArray;

Come ho accennato in precedenza, ho trovato una soluzione per questo: scrivere me stesso il metodo getter, tuttavia quello che sto davvero cercando è una sorta di documentazione di Apple che spieghi questa modifica e qualsiasi altra modifica che non sia correlata all'API.

Grazie per l'aiuto

È stato utile?

Soluzione

Questo è un bug del compilatore.

Anche se non lo hai specificato completamente, mi aspetto che il tuo codice assomigli a questo:

@interface Foo : NSObject {
    NSMutableArray *objects;
}
@property (readonly, copy) NSArray *objects;
@end

@implementation Foo
@synthesize objects;
@end

Purtroppo il compilatore è confuso tra la dichiarazione degli oggetti proprietà e la dichiarazione degli oggetti variabile d'istanza . Ricorda che le proprietà e le variabili di istanza sono cose diverse in Objective-C; una proprietà può essere supportata da una variabile di istanza, ma fa davvero parte dell'interfaccia pubblica di una classe.

Puoi aggirare questo problema modificando il codice per separare chiaramente la definizione della variabile di istanza dalla definizione della proprietà, ad esempio prefissando il nome della variabile di istanza:

@interface Foo : NSObject {
    NSMutableArray *_objects;
}
@property (readonly, copy) NSArray *objects;
@end

@implementation Foo
@synthesize objects = _objects;
@end

In questo modo il compilatore non si confonde sulla proprietà rispetto alla variabile di istanza in espressioni come self.objects (cosa che non dovrebbe comunque, ma apparentemente lo fa).

Giusto per evitare l'inevitabile risposta: Apple non riserva il prefisso della barra inferiore per le variabili di istanza. È riservato ai metodi. Indipendentemente da ciò, se non ti piace il underbar, sentiti libero di usare un altro prefisso.

Altri suggerimenti

modifica: la risposta originale è stata rimossa dopo che la revisione paritaria l'ha trovata carente. Si prega di leggere i commenti di Chris Hanson sull'argomento. Lascio il resto qui perché penso che sia ancora valido.


Si noti che anche se si dichiara il tipo di proprietà NSArray , l'oggetto restituito è ancora un NSMutableArray e i metodi mutabili sono definito per questo. Dichiarare la proprietà in questo modo non impedisce a qualcuno di mutare accidentalmente l'array.

Se si desidera essere certi che l'array restituito non sia modificabile, è possibile dichiarare la proprietà come nell'esempio originale, quindi ruotare il proprio accedente:

- (NSArray *)myArray { return [NSArray arrayWithArray:myArray]; }

Nota che questo restituirebbe un NSArray non mantenuto. Spetterebbe al chiamante assumere la proprietà dell'oggetto se dovesse persistere.

Stai vedendo errori perché XCode ora sta emettendo avvisi ed errori per cose che non ha fatto in precedenza ...

Direi che dovrebbe essere al massimo un avvertimento fare quello che stai facendo, capisco il tuo tentativo di presentare l'array come immutabile al mondo esterno ma lo faccio mutare all'interno della classe. È possibile prendere in considerazione un diverso accessor con un nome diverso, creato per restituire in modo specifico l'array mutabile.

È ancora Objective-C 2.0; il compilatore è forse solo un po 'aggiornato considerando che questo tipo di tipo cambia un errore. Praticamente dovrebbe essere un errore. Almeno dovrebbe avvertirti che probabilmente non intendi quello che hai scritto. Quindi potresti lanciare materiale per evitare che ti avverti, cosa che non puoi fare con l'istruzione @synthesize .

Ho appena incollato esattamente il tuo codice e una dichiarazione di sintesi nel mio controller e non ho ricevuto errori o avvisi a riguardo. Ha costruito bene. Ora ho impostato l'SDK di base su "Simulator 3.0" e la build su "Simulator 3.0 Debug". Questo progetto era iniziato nell'SDK 2.2.1 e ieri ho appena installato l'SDK 3.0; Xcode è la versione 3.1.3.

Aggiorna : oh, vedo che effettivamente provando a impostare la proprietà è dove ottieni l'errore che hai menzionato.

    self.myArray = [NSArray arrayWithObject:@"foo"];

Chiaramente non puoi @synthesize questo comportamento e devi scrivere i tuoi accessi.

- (NSArray*)myArray {
    return [NSArray arrayWithArray:myArray];
}
- (void)setMyArray:(NSArray*) pMyArray {
    myArray = [NSMutableArray arrayWithArray:pMyArray];
}

Compilando questi accessori, il messaggio non è sparito, quindi ho dovuto modificare l'accesso a:

    [self setMyArray:[NSArray arrayWithObject:@"foo"]];

Anche l'uso della sintassi sopra senza accessi personalizzati non ha funzionato.

PS Caspita, qualcun altro è infastidito dal fatto che non puoi né copiare le bolle dei messaggi, né il testo nella finestra dei risultati della compilazione?

Quindi questo ha davvero a che fare con la chiamata @synthesize che non è felice di esporre un NSMutableArray come un NSArray - perché non implementare semplicemente getMethod.

In realtà a pensarci deve essere il metodo set che non è felice - non saresti in grado di impostare un NSArray in un NSMutableArray.

Le tue domande erano:

  

Qualcuno è a conoscenza delle modifiche all'obiettivo-c tra OS 2.2.1 e 3.0?

     

Esiste documentazione per queste modifiche?

Le risposte definitive sono:

1) Non sono state apportate modifiche intenzionali alle specifiche del linguaggio, ma sono stati modificati il ??compilatore e altri strumenti di sviluppo. Chris e i suoi colleghi sono gli esperti di questi cambiamenti.

2) Probabilmente no, perché eventuali modifiche non sono state intenzionali o sono state apportate per abbinare meglio il comportamento con la documentazione.

Non dovresti essere così veloce a respingere la risposta di Chris come " un'ipotesi. " Chris lavora sugli strumenti di sviluppo di Apple. Potresti ottenere un'altra risposta che ti piace di più, ma non otterrai una risposta più esperta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top