6

Genellikle bu gibi onların alıcı yöntemlerinde benim @property nesneleri tembel örneğini:geçersiz kılma özelliği getters

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

@implementation GenericClass 

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

Ama sınıflara, sık sık istiyorum @properties bazı geçersiz kılmak için daha alt sınıflara özgü olmak. Bu yüzden böyle bir şey örnekleme değiştirip yapmak istiyorum:

@interface MySpecificSubclass : MyGenericClass 
//... 

@implementation MySpecificSubclass 

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

Ama alt sınıf _infoImageView Ivar erişemez çünkü, mümkün değildir.

Kötü bir tarz yapmaya çalıştığım şey bu mu? Veya bunun için ortak bir çözüm/en iyi uygulama var mı? Gördüğüm tek çözüm, kapsülleme prensiplerini ihlal etmek gibi hissettiren iVar halkını yapmaktır ...

Bu çok temel bir soru gibi görünüyor, zaten orada milyonlarca cevap olması gerekiyor, ama aradıktan sonra Tüm bulabildiğim saat, Objective-C: Compiler error when overriding a superclass getter and trying to access ivar idi, ancak hiçbir çözüm sağlamaz.

cevap

8

Özellikle birlikte başlık dosyasında korumalı bir değişken olarak _infoImageView bildirmek isteyebilirsiniz. Başka bir fikir, tembel alıcı içinde aramak için genel bir defaultImageView yöntemi oluşturmaktır. Böyle şey:

@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

diğer cevap dediği gibi, bir beyan başlıktaki korumalı değişken. Yeni derleyici normalde buna gerek duymaz, ancak bu durumda aslında yardımcı olur!

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