2010-12-16 16 views
18

मैं अपने UITableView के साथ एक अजीब समस्या मिला दुर्घटनाओं: मैं reloadRowsAtIndexPaths:withRowAnimation: का उपयोग कुछ विशिष्ट पंक्तियों को फिर से लोड करने के लिए, लेकिन एक दूसरे से असंबद्ध लगने अपवाद के साथ ऐप्लिकेशन क्रैश: NSInternalInconsistencyException - अधिक पंक्तियों से अनुभाग में मौजूद हटाने का प्रयास ।reloadRowsAtIndexPaths: withRowAnimation: मेरे ऐप

मेरे कोड इस प्रकार की तरह दिखता है:

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; 

जब मैं की जगह है कि एक साधारण reloadData साथ reloadRowsAtIndexPaths:withRowAnimation: संदेश है, यह पूरी तरह से काम करता है।

कोई विचार?

+1

चेक समान प्रश्न: http://stackoverflow.com/questions/3542260/how-can-i-increase-the-height-of-uitableviewcell-dynamiclly/3542289 यह हो सकता है उपयोगी होगा – Vladimir

उत्तर

9

मुझे लगता है कि निम्नलिखित कोड काम कर सकते हैं:

[self.tableView beginUpdates]; 

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; 

[self.tableView endUpdates]; 
+0

मुझे लगता है कि – Nekto

+0

की मदद नहीं करेगा, इसने मेरी समस्या हल की है। मैं कोर डेटा का उपयोग कर रहा था, और मैंने परिणामफेट कंट्रोलर को एक अलग fetch अनुरोध पारित कर दिया था और लाने के बाद तालिका को फिर से लोड किया था। भले ही fetch था सफल ऐप दुर्घटनाग्रस्त हो गया। लेकिन उपर्युक्त विधि का उपयोग करके पुनः लोड सफल रहा। – prajul

+3

मेरे लिए काम नहीं किया – c0d3Junk13

28

समस्या यह है कि आप, शायद, अपनी मेज के आकार को बदल दिया है है। उदाहरण के लिए, आपने तालिका दृश्य के लिए कुछ स्रोत डेटा जोड़ या हटा दिया है।

उस स्थिति में, जब आप reloadData पर कॉल करते हैं तो आपकी तालिका पूरी तरह से पुनः लोड हो जाती है जिसमें अनुभागों के आकार और उस अनुभाग की संख्या शामिल होती है।

लेकिन जब आप reloadRowsAtIndexPaths:withRowAnimation: पर कॉल करते हैं तो आपके तालिका दृश्य के पैरामीटर पुनः लोड नहीं किए जाते हैं। इससे अगली समस्या होती है: जब आप कुछ सेल तालिका को फिर से लोड करने का प्रयास कर रहे हैं तो तालिका दृश्य का आकार जांचें और देखता है कि यह बदल दिया गया है। इसका परिणाम दुर्घटनाग्रस्त हो गया है। इस विधि का उपयोग तभी किया जा सकता है जब आप सेल के दृश्य को पुनः लोड नहीं करना चाहते हैं (उदाहरण के लिए, लेबल बदल गया है या आप इसका आकार बदलना चाहते हैं)।

अब अगर आप को दूर करने/आप अगले दृष्टिकोण का उपयोग करना चाहिए तालिका दृश्य करने के लिए/से कोशिकाओं को जोड़ना चाहते हैं: डालने के बारे में सूचित UITableView

  • की विधि beginUpdates फोन करके

    1. तालिका को सूचित करें कि इसके आकार बदल जाएगा नई पंक्ति (रों) का उपयोग करते हुए विधि - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
    2. पंक्ति (यों) का उपयोग कर को हटाने विधि - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
    3. की विधि endUpdates फोन करके तालिका को सूचित करें कि इसके आकार बदल दिया गया है के बारे में सूचित

    आशा है कि यह उपयोगी

  • +0

    सैद्धांतिक रूप से समझ में आता है लेकिन काम नहीं करता है। मैं खंडों को फिर से लोड करने की कोशिश कर रहा हूं और यह अभी भी दुर्घटनाग्रस्त है। मैं ऊंचाई के लिए UITableViewAutomaticDimension के साथ अनुमानित हेडर और सेल ऊंचाई का उपयोग कर रहा हूं, इसकी आवश्यकता है। – sheetal

    +0

    @sheetal, अगर आप इस उत्तर में दृष्टिकोण लेते हैं तो आपको reloadRowsAtIndexPaths को कॉल करने की आवश्यकता नहीं है: RowAnimation:। मूल रूप से अपनी मॉडल डेटा संरचना (अधिकांश मामलों में एक सरणी) में एक पंक्ति जोड़ें। फिर startUpdate, insertRowsAtIndexPaths और endUpdates को कॉल करें। – RajV

    1

    इस पुरानी है किया जाएगा। प्रयोग नहीं करें। जब मैं UITextField युक्त एक संपादन कक्ष में सेल को बदलने के लिए reloadRowsAtIndexPaths... पर कॉल कर रहा था, तो मैं बस इस मुद्दे पर टक्कर लगी। त्रुटि ने मुझे बताया कि मैं तालिका में सभी पंक्तियों को हटा रहा था। समस्या को हल करने के लिए, मैं हटा दिया:

    [self.tableView beginUpdates]; 
    NSArray *reloadIndexPath = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:section]]; 
    [self.tableView reloadRowsAtIndexPaths:reloadIndexPath withRowAnimation:UITableViewRowAnimationFade]; 
    [self.tableView endUpdates]; 
    

    और

    [self.tableView reloadData]; 
    
    -2

    मैं आज ही समस्या का सामना करना पड़ रहा से बदल दिया, और यहाँ समाधान मेरे लिए काम नहीं कर रहे थे। मैंने एनीमेशन विधि से पहले [tableView reloadData] पर कॉल करके इसे हल किया। मैं आईओएस 8.3 एसडीके के साथ एक्सकोड 6.3 का उपयोग कर रहा हूँ। उम्मीद है कि यह

    [tableView reloadData]; 
    [tableView reloadRowsAtIndexPaths:indexArray 
           withRowAnimation:UITableViewRowAnimationBottom]; 
    
    +0

    यदि आपने [tableView reloadData] कहा है तो कॉल करने का बिंदु क्या है [tableView reloadRowsAtIndexPaths: withRowAnimation:] विधि उसके बाद। –

    0

    मुझे एक ही समस्या थी।मेरे मामले में; यह तभी हो रहा था जब कोई अन्य व्यू कंट्रोलर मौजूदा टेबल व्यू कंट्रोलर पर पॉप/धक्का दे और फिर [self.tableView reloadRowsAtIndexPaths] फ़ंक्शन को कॉल किया जाता है।

    reloadRowsAtIndexPaths कॉल 30 से अधिक, दृश्यमान जटिल, पंक्तियों वाले तालिका दृश्य में अलग-अलग पंक्तियों को छिपा रहा/दिखा रहा था। जैसे ही मैं इस मुद्दे को ठीक करने का प्रयास करता हूं, मैंने पाया कि यदि मैं टेबल दृश्य को थोड़ा स्क्रॉल करता हूं तो ऐप क्रैश नहीं हो रहा था। अगर मैं सेल को छुपा नहीं जाता (0 ऊंचाई के रूप में 0 लौटकर)

    समस्या को हल करने के लिए, मैंने बस "(CGFloat) तालिका दृश्य: (UITableView *) तालिका बदल दी ऊंचाई देखें ForRowAtIndexPath: (NSIndexPath *) indexPath "फ़ंक्शन और पंक्ति ऊंचाई के रूप में कम से कम 0.01 लौटा।

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
    .... 
    return rowModel.height + 0.01; // Add 0.01 to work around the crash issue. 
    } 
    

    यह मेरे लिए इस मुद्दे को हल करता है।

    3

    मुझे यह समस्या थी जो एक ब्लॉक कॉलिंग reloadRowsAtIndexPaths: withRowAnimation: और समानांतर थ्रेड कॉलिंग reloadData के कारण हुई थी। क्रैश reloadRowsAtIndexPaths के कारण था: RowAnimation एक खाली तालिका ढूंढने के बावजूद, हालांकि मैं संवेदना की जांच की गई संख्या OfRowsInSection & संख्याऑफक्शन।

    मैंने इस दृष्टिकोण को स्वीकार किया कि अगर मुझे अपवाद का कारण बनता है तो मुझे वास्तव में परवाह नहीं है। एक दृश्य भ्रष्टाचार मैं ऐप के उपयोगकर्ता के रूप में पूरे ऐप को क्रैश करने के बजाय जी सकता था।

    यहां मेरा समाधान है जिसे मैं साझा करने में प्रसन्न हूं और रचनात्मक आलोचना का स्वागत करता हूं। यदि कोई बेहतर समाधान है तो मैं इसे सुनना चाहता हूं?

    - (void) safeCellUpdate: (NSUInteger) section withRow : (NSUInteger) row { 
        // It's important to invoke reloadRowsAtIndexPaths implementation on main thread, as it wont work on non-UI thread 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         NSUInteger lastSection = [self.tableView numberOfSections]; 
         if (lastSection == 0) { 
          return; 
         } 
         lastSection -= 1; 
         if (section > lastSection) { 
          return; 
         } 
         NSUInteger lastRowNumber = [self.tableView numberOfRowsInSection:section]; 
         if (lastRowNumber == 0) { 
          return; 
         } 
         lastRowNumber -= 1; 
         if (row > lastRowNumber) { 
          return; 
         } 
         NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section]; 
         @try { 
          if ([[self.tableView indexPathsForVisibleRows] indexOfObject:indexPath] == NSNotFound) { 
           // Cells not visible can be ignored 
           return; 
          } 
          [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; 
         } 
    
         @catch (NSException *e) { 
          // Don't really care if it doesn't work. 
          // It's just to refresh the view and if an exception occurs it's most likely that that is what's happening in parallel. 
          // Nothing needs done 
          return; 
         } 
        }); 
    } 
    
    1

    कई की कोशिश के बाद, मैंने पाया "reloadRowsAtIndexPaths" केवल कुछ स्थानों में इस्तेमाल किया जा सकता है, तो केवल सेल सामग्री को बदलने कोशिकाओं डालने या हटा नहीं सकते। नहीं किसी भी जगह के लिए इसका इस्तेमाल कर सकते हैं, यहां तक ​​कि आप इसे

    [self beginUpdates]; 
    //reloadRowsAtIndexPaths 
    [self endUpdates]; 
    

    स्थानों में लपेट मैंने पाया कि उपयोग कर सकते हैं यह कर रहे हैं:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath - (IBAction) unwindToMealList: (UIStoryboardSegue *) sender

    कोई यह "viewDidLoad" से फोन की तरह अन्य स्थानों से कोशिश या "viewDidAppear", या तो प्रभावी नहीं होगा (पहले से लोड किए गए सेल के लिए मेरा मतलब है, रीलोड प्रभावी नहीं होगा) या अपवाद का कारण बनता है।

    तो केवल उन स्थानों पर "reloadRowsAtIndexPaths" का उपयोग करने का प्रयास करें।

    0

    ऐप क्रैश हो गया है क्योंकि आपने अपनी तालिका में कुछ बदलाव किए हैं। या तो आपने तालिका में कुछ पंक्तियां जोड़ दी हैं या हटा दी हैं। इसलिए जब व्यू कंट्रोलर डेटा के लिए आपके मॉडल कंट्रोलर क्लास से पूछता है, तो इंडेक्सपैथ में एक मेल नहीं है। चूंकि संशोधन के बाद इंडेक्सपाथ बदल गए हैं।

    तो या तो आप बस कॉल

    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade]; 
    

    हटाने या

    [self.tableView reloadData]; 
    

    कॉलिंग reloadData वर्गों की अपनी संख्या की जाँच करता है के साथ बदलने, प्रत्येक अनुभाग में पंक्तियों की संख्या और उसके बाद पूरी बात को पुनः लोड करता।

    0

    आपको पुनः लोड करने से पहले सेल दृश्यता की जांच करनी चाहिए।यहाँ स्विफ्ट है 3 कोड:

     let indexPath = IndexPath(row: offset, section: 0) 
         let isVisible = tableView.indexPathsForVisibleRows?.contains{$0 == indexPath} 
         if let v = isVisible, v == true { 
          tableView.reloadRows(at: [indexPath], with: .automatic) 
         } 
    
    संबंधित मुद्दे