2008-12-31 15 views
5

मैं निम्न उदाहरण वर्ग:उद्देश्य सी NSString * संपत्ति गिनती विषमता को बनाए रखने

Test.h:

@interface Test : UIButton { 
    NSString *value; 
} 
- (id)initWithValue:(NSString *)newValue; 
@property(copy) NSString *value; 

Test.m:

@implementation Test 
@synthesize value; 
- (id)initWithValue:(NSString *)newValue { 
    [super init]; 
    NSLog(@"before nil value has retain count of %d", [value retainCount]); 
    value = nil; 
    NSLog(@"on nil value has retain count of %d", [value retainCount]); 
    value = newValue; 
    NSLog(@"after init value has retain count of %d", [value retainCount]); 
    return self; 
} 

निम्नलिखित में से कौन उत्पादन का उत्पादन:

2008-12-31 09:31:41.755 Concentration[18604:20b] before nil value has retain count of 0 
2008-12-31 09:31:41.756 Concentration[18604:20b] on nil value has retain count of 0 
2008-12-31 09:31:41.757 Concentration[18604:20b] after init value has retain count of 2147483647 

मैं कॉल कर रहा हूँ इसे इस तरह से करें:

Test *test = [[Test alloc] initWithValue:@"some text"]; 

मूल्य 1 की गणना नहीं होना चाहिए? मैं क्या खो रहा हूँ?

आपकी मदद के लिए धन्यवाद।

उत्तर

3

आपको एक अपरिवर्तनीय स्ट्रिंग का संदर्भ मिला है। असाइनमेंट को मान (स्ट्रिंग डेटा) की प्रतिलिपि बनाने की आवश्यकता नहीं है क्योंकि यह अपरिवर्तनीय है। यदि आप एक mutable ऑपरेशन करते हैं, जैसे value = [newValue uppercaseString] तो उसे बिट्स को मान में कॉपी करना चाहिए, और मान की गिनती को बनाए रखा जाना चाहिए।

+1

यह वास्तव में मूल पोस्टर कोड के साथ मौलिक मुद्दों को संबोधित नहीं करता है: वह स्मृति प्रबंधन नियमों का पालन नहीं कर रहा है, और वह संपत्ति के माध्यम से जाने के बजाय सीधे एक आवृत्ति चर निर्दिष्ट कर रहा है। –

10

आप एक शाब्दिक स्ट्रिंग में गुजर रहे हैं। संकलक शायद इसे स्थैतिक स्मृति में आवंटित करता है और अधिकतम संभावित मान पर बनाए रखने की गिनती सेट करता है।

इसके बजाय एक गतिशील आवंटित स्ट्रिंग आज़माएं और देखें कि क्या होता है।

NSString* string = [[NSString alloc] initWithString: @"some text"]; 
Test* test = [[Test alloc] initWithValue: string]; 
+0

यह स्थिर स्मृति में आवंटित कर रहा है भले ही मैं संपत्ति पर कॉपी विशेषता का उपयोग करता हूं? –

+0

यदि आप संपत्ति का उपयोग करना चाहते हैं, तो आपको केवल "value =val" के बजाय "self.value = जो भी" कहना होगा, जो बस आवृत्ति चर निर्दिष्ट करता है। –

+2

किया .. एक ही त्रुटि। मैंने ऊपर गतिशील स्ट्रिंग कोड का उपयोग करने का भी प्रयास किया है। –

3

आप एक स्ट्रिंग स्थिर में गुजर रहे हैं, जिसे वास्तव में हटाया नहीं जा सकता है। मुझे लगता है कि 2147483647 शायद UINT_MAX है, जिसका मूल रूप से मतलब है कि ऑब्जेक्ट जारी नहीं किया जा सकता है।

+0

प्रतिलिपि विशेषता नहीं है एक नई प्रति स्थिर स्मृति में नहीं है? –

+0

उस बिंदु का क्या होगा? आप मान को नहीं बदल सकते हैं, इसलिए आप स्थिर स्मृति पर भी इंगित कर सकते हैं। यह देखने के लिए कि क्या आपको वही व्यवहार मिलता है, यह देखने के लिए एनएसएमयूटेबलस्ट्रिंग को टाइप करने की कोशिश करने लायक हो सकता है। –

+0

मूल रूप से अपरिवर्तनीय होने पर मूल के लिए एक-कॉपी के लिए संभव है, इसलिए एक-कॉपी को समान गारंटी दी जाएगी। –

3

मुझे लगता है कि आप ऐसा करना चाहते हैं:

self.value = newValue; 

जो संपत्ति सेटर आह्वान और नकल होने की कारण होगा। "value = newValue" बस आवृत्ति चर के लिए एक सूचक मान निर्दिष्ट करता है।

+0

धन्यवाद, .. मैंने परिवर्तन किया ..अभी भी वही त्रुटि –

0

हम्म .. हम करीब आ रहे हैं।

ऐसा लगता है कि newValue के बनाए रखने गिनती के बजाय एक ही बनाए रखने गिनती परिणामों के साथ भी 2147483647

मैं गतिशील स्ट्रिंग आवंटन की कोशिश की है। http://www.cocoadev.com/index.pl?NSString

एफटीए:

NSString @ द्वारा दिया है "" रिलीज होने की जरूरत है, या यह autoreleased है

मैं यहाँ एक उपयोगी लेख मिला? न तो। @ "" - स्ट्रिंग्स एनएससीओन्स्टेंटस्ट्रिंग कक्षा के हैं ?, और इस प्रकार परमाणुओं जैसे लिंप में कार्य करते हैं; वे चारों ओर लटका। यही है, अगर आप अपने कोड में दो अलग-अलग स्थानों में @ गाय "का उपयोग करते हैं, तो वे एक ही वस्तु का संदर्भ देंगे। मुझे नहीं लगता -release या -autorelease उनमें से किसी के लिए कुछ भी करता है।

यदि मेरे पास संपत्ति पर "प्रतिलिपि" है, तो क्या यह लक्ष्य स्मृति की सामग्री को नई स्मृति में 1 की बरकरार गिनती के साथ कॉपी नहीं करना चाहिए? ऐसा लगता है कि प्रतिलिपि विशेषता इस मामले में कुछ भी नहीं करती है?

+0

यह मेरी समझ है: जब आप एक अपरिवर्तनीय वस्तु पर "प्रतिलिपि" करते हैं, तो आप वास्तव में इसे बनाए रखते हैं। एक परिवर्तनीय स्ट्रिंग (या अन्य परिवर्तनीय वस्तु) की एक प्रतिलिपि करना वास्तव में इसकी प्रतिलिपि बनाता है। पूरे रखरखाव पर भी लटका मत जाओ। यदि आप रिलीज के साथ हर आवंटन को संतुलित करते हैं तो आप ठीक करेंगे। –

21

गणना को बनाए रखने के लिए मत देखो। वे उपयोगी नहीं हैं और केवल आपको गुमराह करेंगे - आप निश्चित नहीं हो सकते हैं कि कोई वस्तु किसी वस्तु को बरकरार रखती है, कि किसी ऑब्जेक्ट को आप कहीं से प्राप्त नहीं करते हैं।

इसके बजाय, ऑब्जेक्ट स्वामित्व पर ध्यान केंद्रित करें और पत्र में Cocoa memory management rules का पालन करें। इस तरह आपका मेमोरी प्रबंधन सही होगा चाहे कोई भी अनुकूलन कोको आपके लिए दृश्यों के पीछे क्या कर रहा हो। (उदाहरण के लिए, को लागू करने -copy के रूप में सिर्फ अपरिवर्तनीय वस्तुओं के लिए -retain।)

इसके अलावा, यह अपने वस्तुओं की और उदाहरण चर अपने वस्तुओं के भीतर गुणों के बीच के अंतर को समझना महत्वपूर्ण है। आपके प्रश्न के कोड में, आप एक आवृत्ति चर के लिए एक मान असाइन कर रहे हैं। वह इंस्टेंस वैरिएबल बस यही है: एक चर। इसे सौंपना किसी अन्य चर असाइनमेंट की तरह व्यवहार करेगा। संपत्ति का उपयोग करने के लिए, आप वास्तव में संपत्ति के सेटर विधि आह्वान करने के लिए या तो डॉट वाक्य रचना या ब्रैकेट सिंटैक्स का उपयोग करना होगा:

self.value = newValue;  // this is exactly equivalent to the next line 
[self setValue:newValue]; // this is exactly equivalent to the previous line 

कोड डॉट वाक्य रचना और ब्रैकेट वाक्य रचना समान है के लिए उत्पन्न, और न तो उदाहरण चर का उपयोग करेंगे सीधे।

0
#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    char *cstr = "this is a c string"; 

    NSString *str = [[NSString alloc] initWithUTF8String:cstr]; 
    NSLog(@"rc1: %d", [str retainCount]); 

    [pool drain]; 
    return 0; 
} 

आप उपरोक्त कोड चलाते हैं, तो यह 1

0

कोको में की गिनती को बनाए रखने प्रदर्शित करेगा, कई अपरिवर्तनीय वस्तुओं बस खुद को बनाए रखने के लिए जब आप एक ही क्षेत्र के भीतर एक प्रति के लिए पूछेंगे। यदि ऑब्जेक्ट को बदलने की गारंटी नहीं है (यानी इसकी अपरिवर्तनीयता) तो एक सटीक डुप्लिकेट अनावश्यक है।

उद्देश्य-सी में, निरंतर स्ट्रिंग क्लास कोको के NSString वर्ग से अलग है, हालांकि यह NSString (मुझे भी यकीन नहीं है) का उप-वर्ग हो सकता है। यह निरंतर स्ट्रिंग क्लास NSObject की विधियों को ओवरराइड कर सकती है जैसे retain, release और dealloc ताकि वे कुछ भी न करें, और retainCount को ओवरराइड करें ताकि यह हमेशा एक ही संख्या, UINT_MAX या इससे भी अधिक हो। ऐसा इसलिए है क्योंकि स्थैतिक स्मृति में एक उद्देश्य-सी निरंतर स्ट्रिंग बनाई गई है। इसके पास कोको ऑब्जेक्ट (कोको का उपयोग करते समय) का समग्र सामान्य व्यवहार होना चाहिए ताकि इसे मेमोरी में जोड़ा जा सके, जो कि एक मेमोरी प्रबंधन के संबंध में छोड़कर सरणी के रूप में इस्तेमाल किया जा सके, क्योंकि इसे मेमोरी मैनेजमेंट के संबंध में छोड़ दिया गया है, क्योंकि इसे अलग-अलग आवंटित किया गया था।

अस्वीकरण: मुझे वास्तव में पता नहीं है कि मैं किस बारे में बात कर रहा हूं।

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