6

ich in der Regel faul instantiate meine @property Objekte in ihrer Getter-Methoden wie folgt aus:Übergeordnete Eigenschaft Getter mit verzögertes Laden in Objective-C

@interface MyGenericClass : UIViewController 
@property(nonatomic, readonly) UIImageView *infoImageView 
// ... 

@implementation GenericClass 

- (UIImageView *)infoImageView 
{ 
    if (!_infoImageView) { 
     _infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"PlaceholderInfoImage"]]; 
    } 
    return _infoImageView; 
} 

Aber wenn Subklassen, würde ich oft und gerne einige der @properties außer Kraft zu setzen um spezifisch für Unterklassen zu sein. So würde Ich mag die Instanziierung ändern und so etwas wie:

@interface MySpecificSubclass : MyGenericClass 
//... 

@implementation MySpecificSubclass 

- (UIImageView *)infoImageView 
{ 
    if (!_infoImageView) { 
     _infoImageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"SpecialInfoImage"]]; 
    } 
    return _infoImageView; 
} 

Aber das ist nicht möglich, da die Unterklasse nicht den _infoImageView iVar zugreifen kann.

Ist was ich versuche, schlechten Stil zu tun? Oder gibt es eine gemeinsame Lösung/Best Practice dafür? Die einzige Lösung, die ich sehe, ist, den iVar öffentlich zu machen, was das Gefühl hat, die Kapselungsprinzipien zu verletzen ...

Es fühlt sich an, als ob das eine so grundlegende Frage ist, dass es schon Millionen von Antworten gibt, aber nach der Suche stundenlang war alles, was ich finden konnte, Objective-C: Compiler error when overriding a superclass getter and trying to access ivar , aber es bietet keine Lösung.

Antwort

8

Sie möchten möglicherweise _infoImageView als geschützte Variable in der Header-Datei neben der Eigenschaft deklarieren. Eine andere Idee ist es, eine öffentliche defaultImageView Methode zu erstellen, um innerhalb des faulen Getters aufzurufen. Etwas wie folgt aus:

@interface MyGenericClass : UIViewController 
@property (nonatomic, readonly) UIImageView *infoImageView 

...

@implementation GenericClass 

- (UIImageView *)infoImageView 
{ 
    if (!_infoImageView) { 
     _infoImageView = [self defaultImageView]; 
    } 
    return _infoImageView; 
} 

- (UIImageView *)defaultImageView 
{ 
    return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"PlaceholderInfoImage"]]; 
} 

...

@interface MySpecificSubclass : MyGenericClass 

...

@implementation MySpecificSubclass 

- (UIImageView *)defaultImageView 
{ 
    return [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"SpecialInfoImage"]]; 
} 
2

Wie die andere Antwort sagte, erklären ein geschützte Variable in der Kopfzeile. Der neue Compiler benötigt es normalerweise nicht, aber in diesem Fall hilft es tatsächlich!

@interface MyGenericClass : UIViewController{ 
    UIImageView *_infoImageView 
} 
@property(nonatomic, readonly) UIImageView *infoImageView 
Verwandte Themen