6

मैं आमतौर पर आलसी इन्स्तांत इस तरह उनके गेटर तरीकों में मेरी @property वस्तुओं:ऑब्जेक्टिव-सी में आलसी लोड हो रहा है साथ अधिभावी संपत्ति ही टिककर खेल

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

@implementation GenericClass 

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

लेकिन जब उपवर्गीकरण, मैं अक्सर चाहते हैं @properties के कुछ ओवरराइड करने के लिए अधिक subclass विशिष्ट होने के लिए। इसलिए मैं इन्स्टेन्शियशन बदल सकते हैं और की तरह कुछ करना चाहते हैं:

@interface MySpecificSubclass : MyGenericClass 
//... 

@implementation MySpecificSubclass 

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

लेकिन है कि क्योंकि उपवर्ग _infoImageView इवर उपयोग नहीं कर सकते, संभव नहीं है।

क्या मुझे बुरा शैली करने के लिए कोशिश कर रहा हूँ है? या इसके लिए कोई आम समाधान/सर्वोत्तम अभ्यास है? एकमात्र समाधान जो मैं देखता हूं वह है Ivar सार्वजनिक बनाना, जो encapsulation सिद्धांतों का उल्लंघन करने जैसा लगता है ...

ऐसा लगता है कि यह इतना ही बुनियादी सवाल है कि वहां लाखों उत्तरों पहले से ही बाहर हो सकते हैं, लेकिन खोज के बाद घंटों के लिए मुझे लगता है कि Objective-C: Compiler error when overriding a superclass getter and trying to access ivar था, लेकिन यह कोई समाधान प्रदान नहीं करता है।

उत्तर

8

आप संपत्ति के साथ हीडर फ़ाइल में संरक्षित चर के रूप में _infoImageView घोषित करना चाहेंगे। एक और विचार एक सार्वजनिक defaultImageView आलसी गेटर के अंदर कॉल करने के लिए विधि बनाने के लिए है। कुछ इस तरह:

@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

के रूप में अन्य जवाब में कहा, एक की घोषणा हेडर में संरक्षित चर। नए कंपाइलर को आम तौर पर इसकी आवश्यकता नहीं होती है हालांकि इस मामले में यह वास्तव में मदद करता है!

@interface MyGenericClass : UIViewController{ 
    UIImageView *_infoImageView 
} 
@property(nonatomic, readonly) UIImageView *infoImageView 
संबंधित मुद्दे