objective c - उद्देश्य-सी में स्थिरांक




objective-c cocoa (9)

@ Krizz के सुझाव का मामूली संशोधन, ताकि यह ठीक से काम करता है यदि स्थिरांक हेडर फ़ाइल को पीसीएच में शामिल किया जाना है, जो सामान्य है। चूंकि मूल पीसीएच में आयात किया जाता है, इसलिए यह इसे .m फ़ाइल में पुनः लोड नहीं करेगा और इस प्रकार आपको कोई प्रतीक नहीं मिलेगा और लिंकर नाखुश है।

हालांकि, निम्नलिखित संशोधन इसे काम करने की अनुमति देता है। यह थोड़ा उलझन में है, लेकिन यह काम करता है।

आपको 3 फाइलें, .h फ़ाइल की आवश्यकता होगी जिसमें निरंतर परिभाषाएं, .h फ़ाइल और .m फ़ाइल है, मैं क्रमशः ConstantList.h , Constants.h और Constants.m उपयोग करूंगा। Constants.h की सामग्री बस हैं:

// Constants.h
#define STR_CONST(name, value) extern NSString* const name
#include "ConstantList.h"

और Constants.m फ़ाइल इस तरह दिखती है:

// Constants.m
#ifdef STR_CONST
    #undef STR_CONST
#endif
#define STR_CONST(name, value) NSString* const name = @ value
#include "ConstantList.h"

अंत में, ConstantList.h फ़ाइल में वास्तविक घोषणाएं हैं और यह सब कुछ है:

// ConstantList.h
STR_CONST(kMyConstant, "Value");
…

ध्यान देने योग्य कुछ बातें:

  1. मैक्रो के उपयोग के लिए #undef ing के बाद #undef .m फ़ाइल में मैक्रो को फिर से परिभाषित करना पड़ा।

  2. मुझे इसके लिए #include बजाय #import का उपयोग करना होगा ताकि पहले से काम करने के लिए ठीक से काम कर सकें और संकलक से बचें।

  3. जब भी कोई मूल्य बदल जाता है, तो इसके लिए आपके पीसीएच (और संभवतः पूरी परियोजना) के पुनर्मूल्यांकन की आवश्यकता होगी, जो मामला नहीं है अगर वे सामान्य (और डुप्लिकेट) सामान्य के रूप में अलग होते हैं।

उम्मीद है कि किसी के लिए सहायक है।

मैं Cocoa एप्लिकेशन विकसित कर रहा हूं, और मैं निरंतर NSString का उपयोग अपनी वरीयताओं के लिए प्रमुख नामों को स्टोर करने के तरीकों के रूप में कर रहा हूं।

मैं समझता हूं कि यह एक अच्छा विचार है, क्योंकि यदि आवश्यक हो तो यह चाबियों को आसानी से बदल देता है। इसके अलावा, यह पूरी तरह से 'आपके तर्क से अपने डेटा को अलग करें' धारणा है।

वैसे भी, क्या पूरे स्थिरता के लिए इन स्थिरांक को एक बार परिभाषित करने का एक अच्छा तरीका है? मुझे यकीन है कि एक आसान और बुद्धिमान तरीका है, लेकिन अभी मेरी कक्षाएं जो लोग उपयोग करते हैं उन्हें फिर से परिभाषित करती हैं।


आपको एक हेडर फ़ाइल बनाना चाहिए

// Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.

(यदि आप मिश्रित सी / सी ++ वातावरण या अन्य प्लेटफॉर्म पर उपयोग नहीं करेंगे तो आप FOUNDATION_EXPORT बजाय extern उपयोग कर सकते हैं)

आप इस फ़ाइल को प्रत्येक फ़ाइल में शामिल कर सकते हैं जो स्थिरांक का उपयोग करता है या प्रोजेक्ट के लिए पूर्व-संकलित शीर्षलेख में।

आप इन स्थिरांक को एक .m फ़ाइल में परिभाषित करते हैं

// Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";

Constants.m को आपके आवेदन / ढांचे के लक्ष्य में जोड़ा जाना चाहिए ताकि यह अंतिम उत्पाद में जुड़ा हुआ हो।

#define 'डी स्थिरांक के बजाय स्ट्रिंग स्थिरांक का उपयोग करने का लाभ यह है कि आप पॉइंटर तुलना ( stringInstance == MyFirstConstant ) का उपयोग करके समानता के लिए परीक्षण कर सकते हैं जो स्ट्रिंग तुलना ( [stringInstance isEqualToString:MyFirstConstant] स्ट्रिंग [stringInstance isEqualToString:MyFirstConstant] ) से बहुत तेज़ है (और पढ़ने में आसान है, IMO)।


कक्षा विधि का उपयोग करने का प्रयास करें:

+(NSString*)theMainTitle
{
    return @"Hello World";
}

मैं कभी-कभी इसका इस्तेमाल करता हूं।


जैसा कि एबीज़र ने कहा, आप इसे पीसीएच फ़ाइल में डाल सकते हैं। एक और तरीका जो इतना गंदे नहीं है, अपनी सभी चाबियों के लिए फ़ाइल शामिल करना है और उसके बाद उस फ़ाइल में शामिल है जिसमें आप कुंजी का उपयोग कर रहे हैं, या इसे पीसीएच में शामिल करें। उनके साथ फ़ाइल में शामिल हैं, जो कम से कम आपको इन सभी स्थिरांकों को देखने और परिभाषित करने के लिए एक स्थान देता है।


मैं आम तौर पर बैरी वार और राहुल गुप्ता द्वारा पोस्ट किए गए तरीके का उपयोग कर रहा हूं।

हालांकि, मुझे .h और .m फ़ाइल दोनों में एक ही शब्द दोहराना पसंद नहीं है। ध्यान दें, कि निम्न उदाहरण में रेखा दोनों फाइलों में लगभग समान है:

// file.h
extern NSString* const MyConst;

//file.m
NSString* const MyConst = @"Lorem ipsum";

इसलिए, मुझे कुछ सी प्रीप्रोसेसर मशीनरी का उपयोग करना है। मुझे उदाहरण के माध्यम से समझाओ।

मेरे पास एक हेडर फ़ाइल है जो मैक्रो STR_CONST(name, value) को परिभाषित करती है:

// StringConsts.h
#ifdef SYNTHESIZE_CONSTS
# define STR_CONST(name, value) NSString* const name = @ value
#else
# define STR_CONST(name, value) extern NSString* const name
#endif

मेरे .h / .m जोड़ी में जहां मैं निरंतर परिभाषित करना चाहता हूं, मैं निम्न कार्य करता हूं:

// myfile.h
#import <StringConsts.h>

STR_CONST(MyConst, "Lorem Ipsum");
STR_CONST(MyOtherConst, "Hello world");

// myfile.m
#define SYNTHESIZE_CONSTS
#import "myfile.h"

et voila, मेरे पास केवल .h फ़ाइल में स्थिरांक के बारे में सारी जानकारी है।


मैं एक सिंगलटन वर्ग का उपयोग करता हूं, ताकि परीक्षण के लिए आवश्यक हो और मैं स्थिरांक को बदल सकूं। स्थिरांक वर्ग इस तरह दिखता है:

#import <Foundation/Foundation.h>

@interface iCode_Framework : NSObject

@property (readonly, nonatomic) unsigned int iBufCapacity;
@property (readonly, nonatomic) unsigned int iPort;
@property (readonly, nonatomic) NSString * urlStr;

@end

#import "iCode_Framework.h"

static iCode_Framework * instance;

@implementation iCode_Framework

@dynamic iBufCapacity;
@dynamic iPort;
@dynamic urlStr;

- (unsigned int)iBufCapacity
{
    return 1024u;
};

- (unsigned int)iPort
{
    return 1978u;
};

- (NSString *)urlStr
{
    return @"localhost";
};

+ (void)initialize
{
    if (!instance) {
        instance = [[super allocWithZone:NULL] init];
    }
}

+ (id)allocWithZone:(NSZone * const)notUsed
{
    return instance;
}

@end

और इसका उपयोग इस तरह किया जाता है (स्थिरांक सी के लिए शॉर्टेंड के उपयोग पर ध्यान दें - यह हर बार टाइपिंग [[Constants alloc] init] बचाता है):

#import "iCode_FrameworkTests.h"
#import "iCode_Framework.h"

static iCode_Framework * c; // Shorthand

@implementation iCode_FrameworkTests

+ (void)initialize
{
    c  = [[iCode_Framework alloc] init]; // Used like normal class; easy to mock!
}

- (void)testSingleton
{
    STAssertNotNil(c, nil);
    STAssertEqualObjects(c, [iCode_Framework alloc], nil);
    STAssertEquals(c.iBufCapacity, 1024u, nil);
}

@end

यदि आपको नेमस्पेस निरंतर पसंद है, तो आप संरचना का लाभ उठा सकते हैं, शुक्रवार क्यू एंड ए 2011-08-19: नामांकित कॉन्स्टेंट और कार्य

// in the header
extern const struct MANotifyingArrayNotificationsStruct
{
    NSString *didAddObject;
    NSString *didChangeObject;
    NSString *didRemoveObject;
} MANotifyingArrayNotifications;

// in the implementation
const struct MANotifyingArrayNotificationsStruct MANotifyingArrayNotifications = {
    .didAddObject = @"didAddObject",
    .didChangeObject = @"didChangeObject",
    .didRemoveObject = @"didRemoveObject"
};

सबसे आसान उपाय:

// Prefs.h
#define PREFS_MY_CONSTANT @"prefs_my_constant"

बेहतर तरीका:

// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;

// Prefs.m
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";

दूसरे का एक लाभ यह है कि निरंतर के मूल्य को बदलने से आपके पूरे कार्यक्रम का पुनर्निर्माण नहीं होता है।


// Prefs.h
extern NSString * const RAHUL;

// Prefs.m
NSString * const RAHUL = @"rahul";




constants