2012-06-08 4 views
24

In der übergeordneten Klasse MyClass Zugang:-Subklassen der Klasse mit synthetisierten Nur-Lese-Eigenschaft kann nicht Instanz-Variable in Objective-C

@interface MyClass : NSObject 

@property (nonatomic, strong, readonly) NSString *pString; 

@end 

@implementation MyClass 

@synthesize pString = _pString; 

@end 

In der Unterklasse MySubclass

@interface MySubclass : MyClass 

@end 

@implementation MySubclass 

- (id)init { 
    if (self = [super init]) { 
     _pString = @"Some string"; 
    } 
    return self; 
} 

Das Problem ist, dass der Compiler nicht denke, dass _pString ein Mitglied von MySubclass ist, aber ich habe kein Problem in MyClass zugreifen.

Was fehlt mir?

+0

try [super setPString:] oder [self setPString:] – doNotCheckMyBlog

+1

versucht, readonly -Eigenschaft wie folgt zu entfernen @property (nichtatomisch, stark) NSString * pString; – Dinesh

Antwort

50

Die Instanzvariable _pString von @synthesize hergestellt ist privaten zu MyClass. Sie müssen es geschützt machen, damit auf MySubclass zugegriffen werden kann.

eine Ivar Erklärung für _pString im @protected Abschnitt MyClass, wie diese hinzufügen:

@interface MyClass : NSObject { 
    @protected 
    NSString *_pString; 
} 

@property (nonatomic, strong, readonly) NSString *pString; 

@end 

nun die Accessoren wie gewohnt synthetisieren und Ihre Variable wird an Ihre Unterklasse zugänglich.

+0

Sie können den String nicht setzen, wenn er nur gelesen wird !! – doNotCheckMyBlog

+0

Ja, Sie werden ... wenn es aus einer Unterklasse stammt, die Zugriff auf die zugrunde liegende Variable hat. – borrrden

+2

Ich habe es gerade versucht und es funktioniert nicht für mich! – doNotCheckMyBlog

5

Ich bin mit diesem Problem vertraut. Sie synthetisieren die Variable in Ihrer Klasse .m, also wird sie nicht zusammen mit dem Header importiert, da die Variable _pString als Teil der Implementierung und nicht als Schnittstelle erstellt wird. Die Lösung besteht darin, _pString in Ihrer Header-Schnittstelle zu deklarieren und dann trotzdem zu synthetisieren (es wird die vorhandene Variable verwendet, anstatt eine private Variable zu erstellen).

@interface MyClass : NSObject 
{ 
    NSString *_pString; //Don't worry, it will not be public 
} 

@property (nonatomic, strong, readonly) NSString *pString; 

@end 
0

Die angegebene Antwort funktioniert einwandfrei. Dies ist eine alternative Antwort, die anscheinend Apple likes a bit more.

Sie können eine private extension Ihrer Klasse definieren, eine MyClass+Protected.h-Datei, die in MyClass.m und MySubclass.m eingeschlossen werden muss.

In dieser neuen Datei definieren Sie die Eigenschaft dann als readwrite neu.

@interface MyClass() 
@property (strong, readwrite) NSString * pString; 
@end 

Diese Alternative können Sie den Accessor self.pString rathern als die Ivar _pString verwenden.

Hinweis: Sie müssen die Definition von pString in Ihrer MyClass.h unverändert lassen.

Verwandte Themen