6

Tôi thường thuyết minh lười biếng đối tượng @property của tôi trong các phương pháp getter của họ như thế này:getters tài sản Overriding với tải lười biếng trong 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; 
} 

Nhưng khi subclassing, tôi sẽ thường xuyên như để ghi đè lên một số các @properties để có thêm lớp con cụ thể. Vì vậy, tôi muốn thay đổi bản trình bày và thực hiện một số việc như:

@interface MySpecificSubclass : MyGenericClass 
//... 

@implementation MySpecificSubclass 

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

Nhưng điều đó là không thể, vì lớp con không thể truy cập vào _infoImageView iVar.

phải là những gì tôi đang cố gắng để làm phong cách xấu? Hoặc có giải pháp chung/thực tiễn tốt nhất cho việc này không? Giải pháp duy nhất tôi thấy là làm cho công chúng iVar trở nên công khai, có cảm giác như vi phạm nguyên tắc đóng gói ...

Có vẻ như đây là một câu hỏi rất cơ bản, phải có hàng triệu câu trả lời, nhưng sau khi tìm kiếm hàng giờ tôi có thể tìm thấy là Objective-C: Compiler error when overriding a superclass getter and trying to access ivar , nhưng nó không cung cấp giải pháp.

Trả lời

8

Bạn có thể muốn khai báo _infoImageView làm biến được bảo vệ trong tệp tiêu đề cùng với thuộc tính. Một ý tưởng khác là tạo phương thức công khai defaultImageView để gọi bên trong bộ thu gọn. Something như thế này:

@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

Như câu trả lời khác nói, khai báo một biến được bảo vệ trong tiêu đề. Trình biên dịch mới thường không cần nó tuy nhiên trong trường hợp này nó thực sự giúp!

@interface MyGenericClass : UIViewController{ 
    UIImageView *_infoImageView 
} 
@property(nonatomic, readonly) UIImageView *infoImageView 
Các vấn đề liên quan