2014-12-03 7 views
5

का कारण बनता है मैं इस त्रुटि के लिए पूरी तरह से खोज कर रहा हूं और इसी तरह के व्यवहार के साथ कुछ पोस्ट पोस्ट पाई लेकिन समस्या हल करने वाला कोई समाधान नहीं है।मिक्सिंग स्थिर और गतिशील UITableViewController सामग्री NSRangeException

मैं एक UITableViewController जो धारा के लिए है (एस.बी. में स्टेटिक रूप में घोषित किया है): धारा 0 (पकाने की विधि) 4 कोशिकाओं के साथ स्थिर है, धारा 1 (फ्लेवर्स) गतिशील

Storyboard Screenshot

यह वह जगह है होना चाहिए कोड मैं परीक्षण करने के लिए उपयोग कर रहा हूँ:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    rows = [[NSMutableArray alloc] initWithArray:@[@"test",@"test",@"test",@"test",@"test",@"test",@"test"]]; 
} 


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
// Return the number of sections. 
    return 2; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
// Return the number of rows in the section. 
    switch (section) { 
     case 0: 
     return 4; 
     break; 
     case 1: 
     return rows.count; 
     break; 

     default: 
     break; 
    } 

    return 1; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    UITableViewCell *cell; 

    switch (indexPath.section) { 
     case 0: 
     return [super tableView:tableView cellForRowAtIndexPath:indexPath]; 
     break; 

     case 1: 

     cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 
     if (!cell) 
     { 
// create a cell 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; 
     } 
     cell.textLabel.text = [rows objectAtIndex:indexPath.row]; 
     return cell; 

     default: 
     break; 
    } 

    return cell; 
} 

अब त्रुटि मैं जब चल रहा हो रही है: 'NSRangeException', कारण: '*** - [__ NSArrayI objectAtIndex:]: सूचकांक 1 सीमा से परे [0 .. 0] '

मुझे पता है कि मुझे कहीं कुछ छोटा याद आ रहा है, क्या कोई मेरी मदद कर सकता है?

बहुत बहुत धन्यवाद

+0

इस http://stackoverflow.com/a/9428324/285190 – Flexicoder

+0

पर एक नज़र डालें मैं नहीं दिख रहा है कि कैसे अपनी कड़ी में मदद कर किया जाना चाहिए इस मामले के रूप में वर्णित समस्याओं के बराबर मेरे बराबर नहीं है, इसके अलावा मैं एक UITableViewController का उपयोग कर रहा हूं और UIViewController – CRE8IT

+0

नहीं, यह नंबरऑफरोइनसेक्शन के ठीक बाद दुर्घटनाग्रस्त हो जाता है और सेलफ़ोररोएट इंडेक्सपैथ – CRE8IT

उत्तर

6

वास्तविक समस्या यह है कि कैसे गतिशील और स्थैतिक तालिका दृश्य नियंत्रक काम करते हैं।

यदि आप एक गतिशील UITableViewController बनाते हैं, तो अधिकांश विधियां शून्य या 0 या अन्य डिफ़ॉल्ट मान लौटाती हैं। इसलिए यदि आप अपने UITableViewController उपclass में उन्हें ओवरराइट नहीं करते हैं तो कुछ भी बुरा नहीं होता है।

यदि आप एक स्थिर UITableViewController बनाते हैं, तो अधिकांश विधियां स्टोरीबोर्ड को "पूछने" के लिए क्या पूछती हैं। हकीकत में शायद एक बैकिंग स्टोर के रूप में एक निजी सरणी की तरह कुछ है जिसमें सभी आवश्यक डेटा शामिल हैं। और यदि आप इस बैकिंग स्टोर से पूछताछ करने वाले तरीकों को ओवरराइट नहीं करते हैं तो डिफ़ॉल्ट कार्यान्वयन उन इंडेक्स पर ऑब्जेक्ट्स के लिए सरणी से पूछेगा जो मौजूद नहीं हैं।


आपकी समस्या यह है कि आप तालिका बताते हैं कि इसमें 2 अनुभाग और कुछ पंक्तियां हैं।तो tableView स्थिर UITableViewController से दूसरी पंक्ति में दूसरी पंक्ति में सेल की ऊंचाई जैसी चीज़ों के बारे में पूछता है। लेकिन यह इंडेक्सपैथ बैकिंग स्टोर में मौजूद नहीं है (क्योंकि आप केवल दूसरे पंक्ति में एक पंक्ति डालते हैं) जिसका उपयोग स्थिर तालिका दृश्य द्वारा किया जाता है।

तो आपको कुछ डेटा स्रोत और प्रतिनिधि विधियों को लागू करना होगा और तालिका दृश्य दृश्य तालिका स्टोर में मौजूद जानकारी तक पहुंचने के लिए अपने मूल्यों को वापस करना होगा।

यदि आप अपवाद के कॉल स्टैक को देखते हैं तो आपको इन विधियों को देखने में सक्षम होना चाहिए।

उदा .:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]' 
*** First throw call stack: 
(
    0 CoreFoundation 0x000000010ebaaf35 __exceptionPreprocess + 165 
    1 libobjc.A.dylib 0x000000010e843bb7 objc_exception_throw + 45 
    2 CoreFoundation 0x000000010eaa301e -[__NSArrayI objectAtIndex:] + 190 
    3 UIKit    0x000000010f4dc856 -[UITableViewDataSource tableView:heightForRowAtIndexPath:] + 109 
    4 UIKit    0x000000010f21026b __66-[UISectionRowData refreshWithSection:tableView:tableViewRowData:]_block_invoke + 302 
    5 UIKit    0x000000010f20f8fe -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 4125 
    6 UIKit    0x000000010f214e45 -[UITableViewRowData rectForFooterInSection:heightCanBeGuessed:] + 320 
    7 UIKit    0x000000010f214f3a -[UITableViewRowData heightForTable] + 56 

कॉल स्टैक के सूचकांक 3 में आप देख सकते हैं कि -[UITableViewDataSource tableView:heightForRowAtIndexPath:]objectAtIndex: कोड है कि अपवाद उठाया आह्वान किया है। यह उन तरीकों में से एक है जो बैकएंड स्टोर में अपनी कॉल रिले करते हैं यदि आप उन्हें ऐसा करने से नहीं रोकते हैं। तो आपको इस विधि को लागू करना होगा और कुछ उपयोगी वापस करना होगा। और तब तक आप जारी रहते हैं जब तक कि कोई अपवाद नहीं है।

आपकी तालिका की कॉन्फ़िगरेशन पर कितनी विधियों की आवश्यकता हो सकती है। मैं चार है कि आमतौर पर इन अपवादों के कारण लागू किया है, तो आप पैटर्न आप का पालन करना चाहिए यदि आप और अधिक अपवाद नहीं ओवरराइट UITableViewDataSource/प्रतिनिधि तरीकों की वजह से कर रहे हैं देख सकते हैं:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
    CGFloat height = 0; 
    if (section == 0) { 
     // static section 
     height = [super tableView:tableView heightForHeaderInSection:section]; 
    } 
    return height; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 
    CGFloat height = 0; 
    if (section == 0) { 
     // static section 
     height = [super tableView:tableView heightForFooterInSection:section]; 
    } 
    return height; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    CGFloat height = 44; 
    if (indexPath.section == 0) { 
     // static section 
     height = [super tableView:tableView heightForRowAtIndexPath:indexPath]; 
    } 
    return height; 
} 

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSInteger indentationLevel = 0; 
    if (indexPath.section == 0) { 
     // static section 
     indentationLevel = [super tableView:tableView indentationLevelForRowAtIndexPath:indexPath]; 
    } 
    return indentationLevel; 
} 

और यहाँ एक छोटे से है आप गतिशील और स्थिर कोशिकाओं मिश्रण हैं, तो बुला super बहुत उपयोगी हो जाता है

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    if (section == 0) { 
     // static section 
     return [super tableView:tableView numberOfRowsInSection:section]; 
    } 
    return self.objects.count; 
} 

: अपने स्थैतिक सामग्री और भी अधिक अपने कोड से स्वतंत्र बनाने के लिए चाल।

+0

एक व्यवहार्य समाधान दिखाने के अलावा, अब मैं आपकी व्याख्या के लिए प्रक्रिया की पूरी जटिलता को समझता हूं ..मैं इसे एप की कोशिश करूंगा और – CRE8IT

+0

पर वापस रिपोर्ट करूंगा, यह समाधान एक आकर्षण की तरह काम करता है, मैंने यह जवाब सबसे उपयोगी साबित किया क्योंकि यह अपवाद स्टैक के संबंध में प्रक्रिया की पृष्ठभूमि को भी समझाता है ... बहुत बहुत धन्यवाद! – CRE8IT

0

तो ऐसा लगता है जैसे मैं इस त्रुटि आने तक कारण मिल गया। सवाल यह है कि क्या मैंने इसे सही ढंग से हल किया है या प्रोग्रामेटिक रूप से करने का कोई और तरीका है ...

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

एप्लिकेशन चल रहा है, मेरी सरणी केवल 7 वस्तुएं हैं, हालांकि मैं अनुभाग के लिए 30 पंक्तियों सेट, यह केवल 7 सरणी में परिभाषित renders और अन्य 23

प्रदर्शित नहीं करता है ऐसा त्रुटि होने का कारण यह प्रतीत होता है कि जब आप स्थैतिक और गतिशील वर्गों को मिश्रण करना चाहते हैं, तो आपको काम करने के लिए अपनी तालिका को स्थैतिक होने के लिए परिभाषित करना होगा। स्थिर मोड में और एसबी के साथ, ऐसा लगता है जैसे कोड किसी अनुभाग के लिए एसबी में आपके पास मौजूद सेल की संख्या पढ़ता है। यदि यह संख्या आपके डेटा सरणी से छोटी है, तो यह एक NSRangeException थूकता है ...

अभी यह मेरा समाधान है क्योंकि मुझे पता है कि मेरे पास 30 से अधिक कक्ष नहीं होंगे, अगर कोई जानता है कि इस समस्या को कैसे हल किया जाए अधिक गतिशील तरीका, कृपया हमें

1

ऐसा लगता है कि यह व्यवहार छोटा नहीं है। आपको NSIndexPath के साथ सभी विधियों को ओवरराइड करने की आवश्यकता हो सकती है। अधिक जानकारी के लिए आप इस discussion और this one पढ़ सकते हैं।

+0

मुझे ऐप्पल पर एक थ्रेड याद आया, जो सहायक लगता है ... मैं इसे आज़माकर कोशिश करूंगा – CRE8IT

0

मैंने पंक्ति ऊंचाई के लिए UITableViewAutomaticDimension के साथ कॉल को सुपर में बदल दिया और अनुमानित पंक्ति ऊंचाई के लिए प्रतिनिधि विधि को जोड़ा। आईओएस 9 में मुझे उन पंक्तियों के साथ समस्याएं थीं जो विस्तार नहीं कर रही थीं जो आईओएस 8 में स्वचालित रूप से विस्तारित हुई थीं। मेरी स्थैतिक कोशिकाएं गतिशील ऊंचाई भी थीं और गतिशील कोशिकाएं निश्चित ऊंचाई थीं।

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath { 
CGFloat height = 44; 
if (indexPath.section == 0) { 
    // static section 
    height = UITableViewAutomaticDimension; 
} 
return height; 

}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { 
return 44; 

}

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