2009-08-03 8 views
7

मैं उद्देश्य-सी के लिए काफी नया हूं और आईफोन के लिए एक छोटा ऐप बनाने की कोशिश करता हूं।
मैं यहां इस छोटी सी त्रुटि के बगल में लगभग किया गया हूं। असल में, मैंने Google के साथ उचित समाधान खोजने के लिए घंटों की खोज की है लेकिन दुर्भाग्य से मैं एक समाधान ढूंढने में सक्षम नहीं हूं जो काम करता है।
मैं यहाँ इस ट्यूटोरियल का उपयोग कर रहा एक UITableView का निर्माण करने के: UITableView Tutorial पूर्ण त्रुटि संदेश इस प्रकार है:उद्देश्य-सी "अपरिवर्तनीय वस्तु को भेजा गया उत्परिवर्तन विधि" त्रुटि

* समाप्त एप्लिकेशन न आया हुआ अपवाद 'NSInternalInconsistencyException' के कारण, कारण: '* - [ NSCFArray insertObject: atIndex:]: परिवर्तनशील विधि अपरिवर्तनीय ऑब्जेक्ट '

के लिए भेजा यह डाटा नियंत्रक हैडर है: MyLinksDataController.h

@interface MyLinksDataController : NSObject { 

NSMutableArray *tableList; //<---important part 

} 

- (unsigned)countOfList; 
- (id)objectInListAtIndex:(unsigned)theIndex; 
- (void)addData:(NSString *)data; //<---important part 
- (void)removeDataAtIndex:(unsigned)theIndex; 

@property (nonatomic, copy, readwrite) NSMutableArray *tableList; //<---important part 

..... 

और डाटा नियंत्रक विधि: MyLinksDataController.m

#import "MyLinksDataController.h" 

@implementation MyLinksDataController 

@synthesize tableList; 

- (id)init { 

    if (self = [super init]) { 

     NSLog(@"Initilizing DataController"); 
     //Instantiate list 
     NSMutableArray *localList = [[NSMutableArray alloc] init]; 
     self.tableList = [localList copy]; 
     [localList release]; 

     //Add initial Data 
     [self addData:@"AAAAAAAAAAAAAA"]; 
     [self addData:@"BBBBBBBBBBBBBB"]; 

    } 

    return self; 

} 

----------------------------- - स्रोत कोड में लोडर ---------------------------------

- (void)addData:(NSString*)data; { 

    [tableList addObject:data]; //<---- here the app crashes 

} 

मैं चाहता हूं किसी भी मदद की बहुत सराहना करते हैं।

अग्रिम में आपके समर्थन के लिए धन्यवाद।

डैनियल

उत्तर

27

एक NSMutableArray को प्रतिलिपि संदेश भेजा जा रहा - init में निम्नलिखित बयान में के रूप में - एक अपरिवर्तनीय प्रतिलिपि देता है।

self.tableList = [localList copy]; 

कोको प्रलेखन शब्द अपरिवर्तनीय का उपयोग करता है केवल पढ़ने के लिए, नहीं सकते होने वाली बदल के बाद प्रारंभ वस्तुओं उल्लेख करने के लिए। इसलिए बाद में कॉल addObject: त्रुटि संदेश के साथ विफल रहता है।

नोट करें कि उपरोक्त असाइनमेंट कथन किसी भी कंपाइलर चेतावनी को ट्रिगर नहीं करता है। प्रतिआईडी देता है, जो कि कंपाइलर का संबंध है - जहां तक ​​संकलक का संबंध है - NSMutableArray * tableList में। यहां कोई रनटाइम त्रुटि नहीं है, क्योंकि कोई संदेश पास नहीं हुआ है; एक एनएसएआरएआरई पॉइंटर बस एनएसएमयूटेबलएरे पॉइंटर वैरिएबल में रखा जाता है।

एक परिवर्तनीय प्रति प्राप्त करने के लिए, mutableCopy का उपयोग करें।

ध्यान दें कि दोनों प्रतिलिपि और mutableCopy एक नई सरणी बनाने और इसे करने के लिए मूल की सामग्री की नकल। प्रतिलिपि में बदलाव मूल में दिखाई नहीं देगा। यदि आपको मूल सरणी के लिए एक और संदर्भ की आवश्यकता है, तो का उपयोग को इसके बजाय बनाए रखें।

आप copyWithZone reference के चर्चा अनुभाग में और NSMutableCopying protocol reference में अधिक जानकारी प्राप्त कर सकते हैं।

5

आप मूल रूप से कोको (specifically, these details) के मेमोरी प्रबंधन नियमों में भाग ले रहे हैं। यदि immutable version और एक परिवर्तनीय संस्करण वाला कोई ऑब्जेक्ट है, तो किसी ऑब्जेक्ट पर -copy भेजना एक अपरिवर्तनीय ऑब्जेक्ट लौटाएगा।

चलिए प्रासंगिक भाग से आगे बढ़ें।

NSMutableArray *localList = [[NSMutableArray alloc] init]; 

यह आपके पास एक नया, खाली म्यूटेबल सरणी बनाता है जो आपके पास है। ठीक।

self.tableList = [localList copy]; 

यह एक अपरिवर्तनीय खाली सरणी की प्रतिलिपि बनाता है। इसके अलावा, आप इस ताजा बनाई गई प्रतिलिपि के मालिक हैं। इस समय आपके पास दो वस्तुएं हैं।

यह आपकी प्रतिलिपि बनाई गई वस्तु को tableList संपत्ति पर भी निर्दिष्ट करता है। की संपत्ति घोषणा पर नजर डालते हैं:

@property (nonatomic, copy, readwrite) NSMutableArray *tableList; 

यह गुण copy attribute साथ घोषित किया जाता है, इसलिए जब भी कोई नया मूल्य में डाला गया है, एक और -copy विधि इसे करने के लिए भेजा जाता है। हालांकि, यह तीसरी प्रति आपके स्वामित्व में नहीं है - यह वस्तु के स्वामित्व में है।

[localList release]; 

जो मूल खाली म्यूटेबल सरणी जारी करता है। ठीक है, लेकिन अभी भी एक है जो आपने दूसरी पंक्ति में बना दिया है, बिना छेड़छाड़ की। यह एक स्मृति रिसाव है।

यदि आपको वास्तव में किसी चीज़ की एक परिवर्तनीय प्रति की आवश्यकता है, तो आप -mutableCopy विधि चाहते हैं। (इन विधियों के लिए प्रलेखन NSCopying और NSMutableCopying के अंतर्गत पाया गया है।) हालांकि, आपको कभी भी copy विशेषता वाले किसी संपत्ति में कुछ का एक परिवर्तनीय संस्करण नहीं मिल रहा है, क्योंकि यह -copy जो कुछ भी सौंपा गया है उसे भेज देगा। अपनी संपत्ति copy विशेषता के बजाय retain विशेषता का उपयोग करना चाहिए, और कोड प्रारंभ करने में यह कुछ इस तरह दिखना चाहिए:

NSMutableArray *localList = [[NSMutableArray alloc] init]; 
self.tableList = localList; 
[localList release]; 

या, एक छोटा संस्करण:

self.tableList = [NSMutableArray array]; 

कॉपी करने के लिए कोई ज़रूरत नहीं है इस स्थिति में कुछ भी, आप बस एक ताजा वस्तु बना रहे हैं।

+1

एक प्रति संपत्ति वास्तव में, के लिए कहा जाता है तो प्रतिस्थापन एक बनाए रखने संपत्ति एक गरीब समाधान होने जा रहा है। चूंकि कोई mutablecopy कीवर्ड नहीं है, इसलिए संपत्ति को कॉपी के रूप में घोषित करें, लेकिन संश्लेषित एक्सेसर्स का उपयोग करने के बजाय अपना स्वयं का एक्सेसर लिखें। –

+0

अच्छा बिंदु। मैं भी इसमें फेंक दूंगा कि मैं उन वस्तुओं को कभी नहीं देखता जो 'एनएसएमयूटेबलएरे' संपत्ति का विज्ञापन करते हैं। मेरे में शुद्धवादी एक कस्टम सेटर देखना चाहता है जो ऑब्जेक्ट की एक परिवर्तनीय प्रति और एक कस्टम गेटर को स्टोर करता है जो एक ऑटोरेलेज्ड अपरिवर्तनीय प्रतिलिपि देता है। –

0

mutableCopy के बजाय हाय मुझे विश्वास है कि इस समस्या से निपटने के लिए "strong" का भी उपयोग किया जा सकता है। "strong" के बजाय मुझे "copy" का उपयोग करने के कारण भी मेरे कोड में समान समस्या थी। तो नीचे पंक्ति:

@property (copy, nonatomic) NSMutableArray *computers; 

यह होना चाहिए:

@property (strong, nonatomic) NSMutableArray *computers; 

आशा है कि यह शुरुआती मेरे जैसे गलतियों के लिए अपार मदद की हो जाएगा।

1

यदि आप किसी अन्य ऑब्जेक्ट से स्थानीय सूची असाइन कर रहे हैं तो यह उस मामले में उत्परिवर्तनीय नहीं हो सकता है, यह इस तरह की त्रुटि के माध्यम से हो सकता है।

मुझे आशा है कि यह सहायक होगा।

self.tableList = [localList mutableCopy]; 
0

यह समस्या का समाधान हो जाएगा:

NSMutableArray *localList = [[NSMutableArray alloc] init]; 
self.localList = [[NSMutableArray alloc]initWithArray:localList]; 
संबंधित मुद्दे