2010-12-27 11 views
14

मैंने हमेशा सोचा कि कोई श्रेणी में ऑब्जेक्ट प्रॉपर्टी घोषित नहीं कर सकता है। जब तक मेरे साथी ने हमारे ऐप के कोड में ऐसा नहीं किया, और यह काम करना प्रतीत होता था।एक श्रेणी में उद्देश्य-सी 2.0 गुणों को घोषित करना कब संभव है?

मैं उसे एसओ और Google बिंग पर गया ताकि उसे समझाया जा सके कि नहीं, उद्देश्य-सी श्रेणियों का उपयोग केवल विधियों को जोड़ने के लिए किया जा सकता है, गुण नहीं। मैं इस तरह के रूप सवाल पाया:

लेकिन तब मैं एप्पल के साइट पर this link कि @property घोषणा के बारे में निम्नलिखित शामिल पाया:

एक संपत्ति घोषणा कीवर्ड @property से शुरू होती है। @property किसी भी वर्ग के @interface में प्राप्त घोषणा सूची में कहीं भी दिखाई दे सकता है। @property प्रोटोकॉल या श्रेणी की घोषणा में भी दिखाई दे सकता है। (जोर जोड़ा)

मुझे पता है कि यह काम नहीं करता:

@interface MyClass() 
NSInteger foobar; 
- (void) someCategorizedMethod; 
@end 

लेकिन इस संकलित:

@interface MyClass() 
@property NSInteger foobar; 
- (void) someCategorizedMethod; 
@end 

मेरा प्रश्न है (क) क्या यहाँ सबसे अच्छा अभ्यास है? और (बी) यह ऐसा कुछ है जो उद्देश्य-सी 2.0 के लिए नया है, और "असली" iVar का उपयोग करने के बजाय, यह इस काम को करने के लिए दृश्यों के पीछे सहयोगी भंडारण का उपयोग करता है?

उत्तर

31

आप हमेशा एक श्रेणी में @property घोषित करने में सक्षम रहे हैं। आप क्या नहीं कर सकते - और अभी भी नहीं कर सकते - श्रेणी में संपत्ति के लिए भंडारण घोषित नहीं किया गया है, न ही एक आवृत्ति चर के रूप में और न ही @synthesize के माध्यम से।

हालांकि ....

@interface MyClass()एक वर्ग नहीं है। यह एक वर्ग विस्तार है और एक श्रेणी की तुलना में एक विशिष्ट रूप से अधिक विशिष्ट भूमिका है।

अर्थात्, एक वर्ग विस्तार करने के लिए इस्तेमाल किया जा सकता है एक वर्ग के @interface का विस्तार, और इस @properties कि @synthesized जा सकता है (आधुनिक क्रम में भंडारण synthesizing सहित) भी शामिल है।

Foo.h: 

@interface Foo 
@end 

Foo.m: 

@interface Foo() 
@property int x; 
@end 

@implementation Foo 
@synthesize x; // synthesizes methods & storage 
@end 

यह बस इस काम करने के लिए पर्दे के पीछे साहचर्य भंडारण का उपयोग करता है?

नहीं - यह एक वास्तविक उदाहरण चर है। आधुनिक रनटाइम नाजुक बेस क्लास समस्या को हल करता है।


@interface MyClass() 
NSInteger foobar; 
- (void) someCategorizedMethod; 
@end 

ऊपर (उम्मीद के रूप में) काम नहीं करता है, प्रभावी रूप से एक वैश्विक चर क्योंकि foobar है।

आप के लिए इसे बदल हैं:

@interface MyClass() { 
    NSInteger foobar; 
} 
- (void) someCategorizedMethod; 
@end 

तो यह (, सही झंडे के साथ के रूप में @Joshua एक टिप्पणी में किया है) LLVM संकलक की नवीनतम रिलीज के साथ काम करेंगे।

+0

इसमें जोड़ने के लिए, उसका पहला उदाहरण जहां वह एक आईवीआर जोड़ता है, वह पूरी तरह से एलवीएम में -Xclang -fobjc-nonfragile-abi2 –

+1

के साथ मान्य है, अगर वह एक ivar जोड़ रहा होगा। उस स्थिति में, वह एक स्थिर चर जोड़ रहा है जो एक आवृत्ति चर नहीं है। – bbum

+0

व्यापक स्पष्टीकरण के लिए धन्यवाद। मैं अपने कोडिंग भागीदारों के साथ इस लिंक को साझा करूँगा !! – makdad

1

आम तौर पर बोलते हुए, गुण अन्य तरीकों से अलग नहीं हैं। जब तक ivar सामान्य कक्षा में उपलब्ध है, तब तक कोई समस्या नहीं है। यह सिर्फ वाक्य रचनात्मक चीनी है।

कुछ कॉन्फ़िगरेशन में संभव है, जैसे ivar स्वचालित रूप से बनाया गया है, तो चीजें अधिक कठिन हो रही हैं।

मुख्य बिंदु यह है कि ivar की घोषणा संपत्ति से स्वतंत्र है।

1

असीमित भंडारण समाधान है। इस post पर एक नज़र डालें।

+0

फॉलो-अप के लिए धन्यवाद - यह वास्तव में इस मुद्दे के आसपास एक संभावित तरीका है। – makdad