2012-05-17 10 views
11

जब मैं एक संपत्ति की घोषणा, मैं घोषणा में विभिन्न विशेषताओं रख सकते हैं, जो संकलक के लिए विशेष अर्थ होगा:क्या मैं उद्देश्य-सी में सदस्यों पर कस्टम विशेषताओं को निर्दिष्ट कर सकता हूं?

@property (nonatomic, retain) NSNumber *consumption; 

यहाँ, nonatomic और retain विशेषताएँ हैं। क्या एक कस्टम विशेषता जोड़ना संभव है, और रनटाइम पर इस विशेषता के अस्तित्व की जांच करने में सक्षम होना चाहिए? । उदाहरण के लिए: - तो वैकल्पिक सुझावों भी स्वागत कर रहे हैं

@property (nonatomic, retain, test) NSNumber* consumption; 

मैं मूल रूप से एक निर्माण के रूप में मैं उन्हें सी #/नेट से पता है कि विशेषताओं के उपयोग की जगह ले सकता के लिए उपयोग कर रहा हूँ।

+1

http://stackoverflow.com/questions/4919021/custom-property-attributes-in-objective-c – rishi

+0

@ ऋषि, धन्यवाद, लेकिन मैं उस प्रश्न के उत्तर से वास्तव में संतुष्ट नहीं हूं, क्योंकि मेरी विशिष्ट स्थिति मुझे एक और रिटर्न प्रकार बनाने की अनुमति नहीं है। मैं इस पर एक उत्तर की तलाश कर रहा हूं कि यह संभव है या नहीं - और यदि हां, तो कैसे। – driis

+0

यह दुर्भाग्यवश, कंपाइलर को संशोधित किए बिना नहीं है। –

उत्तर

4

आप संकलक को संशोधित किए बिना @property() पर विशेषताओं को जोड़ नहीं सकते हैं।

ध्यान दें कि सामान्य रूप से, रनटाइम पर @property घोषणाओं के मौजूदा विशेषताओं को भी गड़बड़ाना काफी हद तक निराश होता है। रनटाइम एक एपीआई प्रदान करता है जिसके माध्यम से आप ऐसा कर सकते हैं, लेकिन यह सामान्य उद्देश्य के उपयोग के लिए नहीं है और भविष्य में संभावित रूप से बदल जाएगा।

+0

मैंने अभी एक विधि लागू की है जो कक्षा के सभी गुणों के माध्यम से पुनरावृत्त हो जाती है और स्वचालित रूप से एक रेस्टकिट मैपिंग बनाती है। संपत्तियों के माध्यम से परेशान क्यों है? – Nick

+0

@ निक यह नाजुक है। कोई व्यक्ति मनमाने ढंग से श्रेणी या सुपरक्लास में संपत्ति जोड़ सकता है। या कोई संपत्ति घोषणा के बिना एक सेटर/गेटर विधि जोड़ी बना सकता है। या कोई ऐसी संपत्ति घोषित कर सकता है जिसका आपके RestKit मानचित्रण में भाग लेने का इरादा नहीं है। अंत अनुप्रयोगों की तुलना में ढांचे के कार्यान्वयन के लिए अधिक मुद्दे, लेकिन आपको शायद यह पता चल जाएगा कि एक स्पष्ट "+ (एनएसएआरएआरए *) विशेषताएँ पार्टनरिंगइनरस्टमैपिंग" टाइप क्वेरी विधि समय के साथ रखरखाव सिरदर्द को कम कर देगी। उस सेट में मैन्युअल रूप से जोड़ने के लिए देव को मैन्युअल रूप से बहुत कठिन नहीं है और यह स्वयं दस्तावेज है। – bbum

0

आप गुणों के एनएसएआरएआरई में संपत्ति नामों का NSDictionary हमेशा जोड़ सकते हैं। इसे मूल श्रेणी या एक अलग वर्ग में संग्रहीत किया जा सकता है जो मूल वस्तु से objc_setAssociatedObjects और objc_getAssociatedObjects API के माध्यम से जुड़ा हुआ है।

इन API पर जानकारी के लिए here देखें। यह वही नहीं है जो आप खोज रहे हैं क्योंकि आपको कंपाइलर को बदलने की आवश्यकता होगी, लेकिन किसी ऑब्जेक्ट में मेटाडेटा जोड़ने का एक तरीका है।

0

संपत्ति में कस्टम विशेषताओं को जोड़ना आम नहीं है लेकिन मुझे लगता है कि वांछनीय है। इस सुविधा का उपयोग कक्षा के गुणों के बारे में ट्रैवर्सल के लिए किया जा सकता है। जब मैं SQL को संभालता हूं तो मैं इस सुविधा को वांछित करता हूं: यदि हमारे पास विशेषताएं हैं: EXCLUDE_FROM_SELECT, INCLUDE_BY_INSERT, EXCLUDE_FROM_UPDATE ... तो यह बहुत अच्छा होगा।

दरअसल, मुझे यकीन नहीं है कि @property निर्देश के लिए इसे सक्षम करने का कोई तरीका है या नहीं। हालांकि, हम कुछ ऐसा करने के लिए सक्षम हो सकते हैं:

यदि आप objc/runtime.h पर एक नज़र डालते हैं तो आपको एक फ़ंक्शन मिल सकता है: class_replaceProperty, जो ऑफिकल वेबसाइट में प्रलेखित नहीं है। class_addProperty नामक एक समान फ़ंक्शन को दस्तावेज किया गया है और पिछले एक के तर्क को समझने में आपकी सहायता कर सकता है। असल में, मुझे लगता है कि @property संपत्ति कार्यों को करने के लिए इस फ़ंक्शन का उपयोग करता है (लेकिन मैं यह सबूत नहीं कर सकता)।

तुम भी निम्नलिखित कार्य की आवश्यकता हो सकती:

void class_copyPropertyList(...); 
void property_copyAttributeList(...); 
void class_getProperty(...); 

इन कार्यों का उपयोग करके, आप कुछ क्या @property लेकिन वास्तव में ऐसा कर सकता है।

क्या मैं पिछले एसक्यूएल समस्या के लिए किया था कस्टम रजिस्टर करने के लिए 3 कार्यों का श्रेय परिभाषित करने के लिए है:

void prepareClass(...); 
void registerAttributes(...); 
void endRegister(...); 

और फिर हम अपने tagart वर्ग के +initialize समारोह में रजिस्टर कर सकता है।

हालांकि, कोड का उपयोग करना (सरल @interface + @property घोषणा के साथ तुलना करें) आपका सबसे अच्छा समाधान नहीं हो सकता है, क्योंकि हम सीधे घोषणा से संपत्ति सेटिंग्स देखना चाहते हैं।और वास्तव में हम इसे बेहतर __attribute__((constructor)) और मैक्रो का उपयोग करके कर सकता है:

@interface @end वास्तव में अनुमति देते हैं यदि आप ऐसा करने: इसलिए

@interface MyVO : NSObject 
__attribute__((constructor)) 
void prepareForMyVO(){ prepareClass(MyVO);} 
@property (strong) id p1; 
__attribute__((constructor)) 
static void registerAttrForP1(){ registerAttributes("p1", EXCLUDE_FROM_SELECT);} 
@property (strong) id p2; 
__attribute__((constructor)) 
static void registerAttrForP2(){ registerAttributes("p2", INCLUDE_BY_INSERT);} 
@end 
__attribute__((constructor)) 
static void endRegisterForMyOV(){ endRegister();}; 

, तो आप इस hardcode को संभालने के लिए अपने मैक्रो निर्धारित कर सकते हैं:

#define $p(clazz, zuper) class : zuper \ 
__attribute__((constructor)) static void prepareFor ## clazz(){ prepareClass(#MyVO);} 
#define $r(p, attr) p; \ 
__attribute__((constructor)) static void registerAttrFor ## p(){ registerAttributes(#p, attr);} 
#define $e(clazz) __attribute__((constructor)) static void endRegister ## clazz(){ endRegister();}; 



@interface $p(MyVO, NSObject) 
@property (strong) id $r(p1, EXCLUDE_FROM_SELECT); 
@property (strong) id $r(p1, INCLUDE_BY_INSERT); 

@end $e(MyVO) 

पीएस: उपरोक्त कोडिंग सटीक कोडिंग नहीं है, यह सिर्फ एक उदाहरण है। और मुझे यकीन नहीं है कि अंतिम मैक्रो समाधान काम करता है, उम्मीद है कि यह मदद कर सकता है।

संबंधित मुद्दे

 संबंधित मुद्दे