objective c - Objective-C-proprietà di sola lettura non sintetizzate con l'undersar ivar?



cocoa synthesize (1)

Se ho capito bene, in Objective-C, le proprietà sono automaticamente sintetizzate con getter e setter, con la variabile di istanza dichiarata come nome della proprietà con un underscore anteposto ( _ivar ).

Quindi, questo codice:

main.m

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

int main(int argc, char *argv[])
{

    @autoreleasepool {

        Hello *hello = [[Hello alloc] init];
        NSLog(@"%@", hello.myString);

        return 0;

    }

}

Ciao h

#import <Foundation/Foundation.h>

@interface Hello : NSObject
@property (copy, nonatomic) NSString *myString;
@end

hello.m

#import "hello.h"

@implementation Hello

-(Hello *)init
{

    if (self = [super init]) {
        _myString = @"Hello";
    }

    return self;

}

-(NSString *)myString
{
    return [NSString stringWithFormat:@"%@ %@", _myString, @"World"];
}

@end

Può essere compilato ed eseguito in questo modo:

bash-3.2$ clang -framework Foundation main.m hello.m -o hello
bash-3.2$ ./hello
2013-05-27 13:20:39.738 hello[23320:707] Hello World

Ora quando cambio la proprietà myString a readonly in questo modo:

@property (readonly, copy, nonatomic) NSString *myString;

Poi, quando provo a compilare, ottengo un errore:

hello.m:11:9: error: unknown type name '_myString'; did you mean 'NSString'?
        _myString = @"Hello";
        ^~~~~~~~~
        NSString

Quindi _myString non è definito. Il compilatore non ha sintetizzato la proprietà con la variabile di istanza _myString? Vediamo se funziona quando lo sintetizzo da solo:

Nell'implementazione hello.m:

@synthesize myString = _myString;

Ora funziona di nuovo:

bash-3.2$ clang -framework Foundation main.m hello.m -o hello
bash-3.2$ ./hello
2013-05-27 13:36:59.916 hello[24219:707] Hello World

Quindi, la mia domanda è: perché non viene automaticamente sintetizzata con un underscore ivar quando si utilizza readonly sulle proprietà? O sono totalmente sulla strada sbagliata per capire come funziona questa roba Objective-C?

Gradirei molto una risposta esplicativa, poiché voglio davvero capire cosa sta succedendo e perché.

Grazie in anticipo.


Una proprietà non viene automaticamente sintetizzata se si implementano tutti i metodi accessor richiesti (getter per una proprietà di sola lettura, getter + setter per una proprietà read-write).

Poiché si implementa il metodo getter -(NSString *)myString per la proprietà di sola lettura, non viene automaticamente sintetizzato. Se il tuo getter ha bisogno di una variabile di istanza per eseguire il backup del valore della proprietà, devi aggiungere l'istruzione synthesize (come hai fatto tu) o una variabile di istanza.





synthesize