सवाल उद्देश्य सी स्थैतिक वर्ग चर


मैं उद्देश्य सी के लिए नया हूं और स्टीवन होल्ज़नर, पीचिपिट प्रेस द्वारा "विजुअल क्विकस्टार्ट गाइड: ऑब्जेक्टिव-सी" नामक पुस्तक पढ़ रहा हूं

अध्याय 6 में: ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग, क्लास वेरिएबल का उपयोग करने वाला एक अनुभाग है जहां वह लिखता है:

आप के साथ उपयोग के लिए कक्षा चर बना सकते हैं   आपकी कक्षाएं, लेकिन एक झटका है: हर वस्तु   उस वर्ग का एक ही वैरिएबल साझा करता है, इसलिए   यदि एक ऑब्जेक्ट क्लास वेरिएबल बदलता है, तो   परिवर्तनीय सभी वस्तुओं के लिए बदल दिया गया है। तुम बनाते हो   स्थैतिक कीवर्ड के साथ कक्षा चर।   कक्षा चर अक्सर उपयोगी होते हैं: उदाहरण के लिए,   आप ट्रैक रखने के लिए एक वर्ग चर का उपयोग कर सकते हैं   बनाए गए किसी विशेष वर्ग की वस्तुओं की संख्या   एक कार्यक्रम में आप इस कार्य में ऐसा करेंगे।

और निम्नलिखित कोड दर्ज करने के लिए कहते हैं:

#import <stdio.h>
#import <Foundation/NSObject.h>
@interface TheClass: NSObject
static int count; //error: cannot declare variable inside @interface or @protocol
+(int) getCount;
@end
...

यह कोड मुझे एक्सकोड 4 में एक त्रुटि देता है:

@Interface या @protocol के अंदर चर घोषित नहीं कर सकता

क्या किताब गलत है या क्या मैं कुछ गलत कर रहा हूं?


44
2018-05-17 19:07


मूल


पुस्तक पूरी तरह गलत है, उद्देश्य-सी में कक्षा चर की कोई अवधारणा नहीं है। आप स्थिर चर घोषित कर सकते हैं जिस तरह से सी में किया जाएगा, लेकिन वे वर्गों से कम नहीं हैं (कम से कम, अर्थात् नहीं)। - BoltClock♦


जवाब:


आप कार्यान्वयन फ़ाइल में स्थिर चर घोषित करते हैं (.m फ़ाइल)। यह काम करना चाहिए:

// TheClass.h
@interface TheClass : NSObject
+ (int)count;
@end

// TheClass.m
static int theCount = 0;

@implementation TheClass
+ (int) count { return theCount; }
@end

यह प्रति वर्ग वर्ग नहीं है; उद्देश्य-सी में कक्षा चर का कोई विचार नहीं है। हालांकि, इस चर को पुनः प्राप्त करने के लिए कक्षा विधि के साथ, यह एक वर्ग चर के समान कार्य करता है। हालांकि, यह वास्तव में केवल एक सी स्थिर चर है जो वर्ग के कार्यान्वयन से सुलभ है।


95
2018-05-17 19:13



क्या होगा यदि "क्लास वेरिएबल" एक ऑब्जेक्ट है (NSSet कहें), जिसके लिए कुछ प्रारंभिक आवश्यकता है? - Uri
@ मिपादी - कृपया मेरे लिए स्पष्टीकरण दें। मुझे "क्लास वेरिएबल" की परिभाषा के बारे में निश्चित नहीं है और इसलिए मुझे यकीन नहीं है कि मैं समझता हूं कि "यह कक्षा चर नहीं है।" कार्यान्वयन फ़ाइल में घोषित एक स्थैतिक चर वर्ग के सभी उदाहरणों द्वारा साझा किया जाता है और केवल उस वर्ग के उदाहरणों द्वारा सुलभ होता है। क्या यह "वर्ग परिवर्तनीय" नहीं है क्योंकि यह सबक्लास द्वारा सुलभ नहीं है? या क्या कोई अन्य कारण है कि आप भेद कर रहे हैं? मैं ईमानदारी से सीखना पसंद करूंगा। - Chuck Krutsinger
@ चक-क्रुटिंगर जैसा कि किसी और ने उत्तर दिया है: क्लास वेरिएबल की अवधारणा एक क्लास विधि (लेकिन एक चर) के समान है यानी एक वेरिएबल जिसे क्लास का उदाहरण बनाये बिना एक्सेस किया जा सकता है, जो बिल्कुल स्थिर है कार्यान्वयन में परिवर्तनीय होगा। 'क्लास वेरिएबल' शब्द का उपयोग करने का कारण यह है कि सवाल यही था, लेकिन वे मौजूद नहीं हैं क्योंकि स्थैतिक पहले से ही आवश्यक कार्यक्षमता प्रदान करता है। - Simon Jackson
कक्षा के लिए '' (शून्य) प्रारंभिक '' का उपयोग करें (जावा या सी # में एक स्थिर निर्माता का एनालॉग) - Julian Gold
अरे मैंने कुछ समय पहले एक गलती की थी, एआरसी संगत नहीं, लेकिन वास्तव में इसे असाइन विधियों का उपयोग करके और मजबूत या कमजोर संदर्भ निर्दिष्ट करके एआरसी में उपयोग किया जा सकता है। gist.github.com/darionco/03649feeee57f86fee3f - Dario


मैंने यूनिक्स के बारे में एक विजुअल क्विकस्टार्ट गाइड देखा है और यह बड़ा समय चूस गया है। यह नमूना से कम से कम बेहतर प्रतीत नहीं होता है। उद्देश्य-सी में कक्षा चर बनाने का सही तरीका इस तरह दिखता है:

// Counted.h
@interface Counted : NSObject

+ (NSUInteger) numberOfInstances;

@end

// Counted.m
#import "Counted.h"

static NSUInteger instances = 0;

@implementation Counted

- (id) init {
    …
    instances++;
    …
}

- (void) dealloc {
    instances--;
}

+ (NSUInteger) numberOfInstances {
    return instances;
}

@end

यह वास्तव में एक स्थिर चर है, एक वास्तविक वर्ग परिवर्तनीय नहीं है। लेकिन आपको कक्षा चर के बारे में चिंता करने की ज़रूरत नहीं है, वैसे भी वे एक संकेत हैं कि आप कुछ गलत कर रहे हैं। (मैं थोड़ा बढ़ा रहा हूं, लेकिन ज्यादा नहीं।)

यदि आप एक सभ्य उद्देश्य-सी पुस्तक की तलाश में हैं, तो पढ़ें ऐप्पल द्वारा एक। यह मुफ़्त है और यह एक अच्छी पढ़ाई है।


15
2018-05-17 19:13





यदि "क्लास वेरिएबल" को तुच्छ प्रारंभिक से अधिक की आवश्यकता है, तो इसका उपयोग करें dispatch_once:

@interface Foo ()
+ (Foo *)singleton;
@end

+ (Foo *)singleton {
    static Foo *_singleton;
    static dispatch_once_t oncePredicate;

    dispatch_once(&oncePredicate, ^{
        _singleton = [[Foo alloc] init];
    });

    return _singleton;
}

9
2018-03-14 15:19





आपको .m फ़ाइल में चर घोषित करना चाहिए, जहां @ कार्यान्वयन रखा गया है। इसलिए,

#import "TheClass.h"

static int count;

@implementation

...

@end

यह ध्यान रखना महत्वपूर्ण है कि उद्देश्य-सी वास्तव में वर्ग चर का समर्थन नहीं करता है। लेकिन आप उन्हें स्थैतिक चर के साथ अनुकरण कर सकते हैं, क्योंकि हम यहां कर रहे हैं।


6
2018-05-17 19:18