菜鸟教程小白 发表于 2022-12-12 18:14:12

ios - uitableview 更新错误


                                            <p><p>我使用以下方法更新表格 View 单元格:</p>

<pre><code>
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{
    NSArray *arr = ;
    if ()
    {
      UITableViewCell *cell = ;//received error here
      UIImageView *imageView = (UIImageView *);
      SDWebImageManager *manager = ;
      UIImage *image = ;
      imageView.image = image;
    }
}

</code></pre>

<p>这是 <code>SDWebImageDownloader</code> 的委托(delegate),更新时收到错误:</p>

<pre>thread9:Program received signal: &#34;SIGABRT&#34;.
</pre>

<p>Form the device console, there is:</p>

<pre>: *** Terminating app due to uncaught exception &#39;NSRangeException&#39;, reason: &#39;*** -: index 7 beyond bounds &#39;
    *** First throw call stack:
    (0x335a38bf 0x300971e5 0x334ecb6b 0x30ff0eb1 0xaa0a7 0x334fd435 0xb5b13 0x30d91a91 0x30e255a1 0x36fa0c1d 0x36fa0ad8)
</pre>

<p>Then I print the <code>arr</code> which holds the current visible index path:</p>

<pre>Printing description of arr:
(
    &#34; 2 indexes &#34;,
    &#34; 2 indexes &#34;,
    &#34; 2 indexes &#34;,
    &#34; 2 indexes &#34;,
    &#34; 2 indexes &#34;,
    &#34; 2 indexes &#34;,
    &#34; 2 indexes &#34;
)
</pre>

<p>and the received <code>indexPath</code></p>

<pre> 2 indexes
</pre>

<p>The indexPath is included in the visible index path, and why it still cause the <code>NSRangeException</code>?
It looks like a bug for <code>cellForRowAtIndexPath:indexPath</code>, as the row of index path is 7 which is beyond the visible index path arr, am I right?</p>

<p>Add the eatableview delegate method:</p>

<pre><code>
- (UITableViewCell *)tableView:(UITableView *)inTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @&#34;Cell&#34;;

    NSString *path;
    NSString *filename;

    BOOL download = YES;
    NSDictionary *tempDic = nil;
    @synchronized (documentDirectoryFileList) {
      tempDic = ;
      filename = ;

      NSURL *url = ;
      if ( url ) {
            path = [ url path ];
            download= [ self downloadedFile:url ];

      } else {

                path = ;
      }
    }

    BOOL isDirectory = FALSE;

    NSFileManager *fileManager = [ init];
    BOOL found = ;

    UITableViewCell *cell = ;
    if (cell == nil) {
      cell = [[ initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

      CGRect rect;
      rect = CGRectMake(5,14, 32, 32);

      cell.userInteractionEnabled = YES;

      UIImageView *imageView = [ initWithFrame:rect];
      imageView.tag = &#39;ICON&#39;;
      ;
      ;      

      rect = CGRectMake(42, 10, 238, 22);

      UILabel *labelView = [ initWithFrame:rect];
      labelView.tag = &#39;NAME&#39;;
      labelView.font = ;
      if ( download == NO )
            labelView.textColor = ;
         ;
      ;

      rect = CGRectMake(42, 34, 200, 20);
      labelView = [ initWithFrame:rect];
      labelView.tag = &#39;TIME&#39;;
      labelView.font = ;
      if ( download == NO )
            labelView.textColor = ;
      ;
      ;

      rect = CGRectMake(200, 34, 75, 20);
      labelView = [ initWithFrame:rect];
      labelView.tag = &#39;SIZE&#39;;
      labelView.font = ;
      if ( download == NO )
            labelView.textColor = ;
      labelView.textAlignment = UITextAlignmentRight;
      ;
      ;

    }


    // Get the time zone wrapper for the row
    UIImageView *imageView = (UIImageView *);
    imageView.image = NULL;

    NSString* extension = [ lowercaseString];
    if ( ||
       ||
       ||
       ||
       ||
       ||
      )
    {
      NSString *realFilePath = [ fileManager destinationOfSymbolicLinkAtPath:path error:nil ];
      if ( realFilePath )
            path = realFilePath;

      NSURL *url = [ URLByAppendingPathComponent:@&#34;thumb.th&#34;];
      SDWebImageManager *manager = ;
      UIImage *temp = ;
      if (temp) {
            imageView.image = temp;
      }
      else
      {
            SDWebImageDownloader *downloader = ;
      }

    } else {

      imageView.image = [ self determineFileIcon : path ];

    }

    // Configure the cell.
    UILabel *labelView = (UILabel *);
    labelView.text = filename;
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    if ( isDirectory ) {
      if ( isLink( path ) )
            labelView.font = ;
      else
            labelView.font = ;
    } else {
      if ( isLink( path ) )
            labelView.font = ;
      else
            labelView.font = ;
    }

    labelView = (UILabel *);
    NSCalendar *theCalendar= [ initWithCalendarIdentifier:NSGregorianCalendar];
    NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;

    NSDate *date = ;
    NSDateComponents *dateComponents = ;

    NSInteger year = ;
    NSInteger month = ;
    NSInteger day = ;
    NSInteger hour = ;
    NSInteger minute = ;
    NSInteger second = ;

    ;
    labelView.text = ;

    if ( !isDirectory ) {
      labelView = (UILabel *);
      ;
      NSNumber *size = ;
      float value = [ size floatValue ];
      NSString *str;
      if ( value &gt; ( 1024*1024 ) ) {
            value = value / 1024 / 1024;
            str = ;
      } else if ( value &gt; 1024 ) {
            value = value / 1024;
            str = ;
      } else {
            str = ];
      }
      labelView.text = str;
    }
    else
    {
      labelView = (UILabel *);
      ;
    }

    ;

    return cell;
}
</code></pre>

<p>添加于 11-17:
当“SIGABRT”收到时,<code>documentDirectoryFileList</code> 有对象,例如 30+。接收到的 indexPath 存在于可见索引路径数组中。但我注意到:滚动表格 View 时很容易发生。没有新对象添加到数据源。我所做的只是更新单元格上的图像。</p>

<p>我猜可能是:
当接收到的索引路径开始更新相应的单元格时,我碰巧滚动它并且单元格或索引路径不再可见。然后它崩溃了。 </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>这似乎是多线程的一种问题。</p>

<pre><code>
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{


    @synchronized(tableView)
    {
      NSArray *arr = ;
      if ()
      {

            UITableViewCell *cell = ;
            if (!cell)
            {
                return;
            }

            UIImageView *imageView = (UIImageView *);
            SDWebImageManager *manager = ;
            UIImage *image = ;
            if (image) {
                dispatch_async(dispatch_get_main_queue(), ^{
                  imageView.image = image;
                });

            }
      }

    }
}
</code></pre>

<p>或者你可以</p>

<pre><code>
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{


    @synchronized(tableView)
    {
      NSArray *arr = ;
      if ()
      {

            dispatch_async(dispatch_get_main_queue(), ^{
                   withRowAnimation:UITableViewRowAnimationNone];
                });//must be in main thread; reloadRowsAtIndexPaths: is not thread safe



      }

    }
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - uitableview 更新错误,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/8148811/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/8148811/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - uitableview 更新错误