我使用以下方法更新表格 View 单元格:
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{
NSArray *arr = [self.tableView indexPathsForVisibleRows];
if ([arr containsObject:indexPath])
{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];//received error here
UIImageView *imageView = (UIImageView *)[cell viewWithTag:'ICON'];
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *image = [manager imageWithURL:downloader.url];
imageView.image = image;
}
}
这是 SDWebImageDownloader 的委托(delegate),更新时收到错误:
thread9: Program received signal: "SIGABRT".
Form the device console, there is:
: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 7 beyond bounds [0 .. 6]'
*** First throw call stack:
(0x335a38bf 0x300971e5 0x334ecb6b 0x30ff0eb1 0xaa0a7 0x334fd435 0xb5b13 0x30d91a91 0x30e255a1 0x36fa0c1d 0x36fa0ad8)
Then I print the arr which holds the current visible index path:
Printing description of arr:
(
" 2 indexes [0, 1]",
" 2 indexes [0, 2]",
" 2 indexes [0, 3]",
" 2 indexes [0, 4]",
" 2 indexes [0, 5]",
" 2 indexes [0, 6]",
" 2 indexes [0, 7]"
)
and the received indexPath
2 indexes [0, 7]
The indexPath is included in the visible index path, and why it still cause the NSRangeException?
It looks like a bug for cellForRowAtIndexPath:indexPath, as the row of index path is 7 which is beyond the visible index path arr, am I right?
Add the eatableview delegate method:
- (UITableViewCell *)tableView:(UITableView *)inTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
NSString *path;
NSString *filename;
BOOL download = YES;
NSDictionary *tempDic = nil;
@synchronized (documentDirectoryFileList) {
tempDic = [self.documentDirectoryFileList objectAtIndex:indexPath.row];
filename = [tempDic objectForKey:@"filename" ];
NSURL *url = [tempDic objectForKey:@"url" ];
if ( url ) {
path = [ url path ];
download= [ self downloadedFile:url ];
} else {
path = [tempDic objectForKey:@"filepath" ];
}
}
BOOL isDirectory = FALSE;
NSFileManager *fileManager = [[NSFileManager alloc] init];
BOOL found = [fileManager fileExistsAtPath: path isDirectory: &isDirectory];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
CGRect rect;
rect = CGRectMake(5,14, 32, 32);
cell.userInteractionEnabled = YES;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:rect];
imageView.tag = 'ICON';
[cell.contentView addSubview:imageView];
[imageView release];
rect = CGRectMake(42, 10, 238, 22);
UILabel *labelView = [[UILabel alloc] initWithFrame:rect];
labelView.tag = 'NAME';
labelView.font = [UIFont boldSystemFontOfSize:18];
if ( download == NO )
labelView.textColor = [UIColor lightGrayColor ];
[cell.contentView addSubview:labelView];
[labelView release];
rect = CGRectMake(42, 34, 200, 20);
labelView = [[UILabel alloc] initWithFrame:rect];
labelView.tag = 'TIME';
labelView.font = [UIFont systemFontOfSize:12];
if ( download == NO )
labelView.textColor = [UIColor lightGrayColor ];
[cell.contentView addSubview:labelView];
[labelView release];
rect = CGRectMake(200, 34, 75, 20);
labelView = [[UILabel alloc] initWithFrame:rect];
labelView.tag = 'SIZE';
labelView.font = [UIFont systemFontOfSize:12];
if ( download == NO )
labelView.textColor = [UIColor lightGrayColor ];
labelView.textAlignment = UITextAlignmentRight;
[cell.contentView addSubview:labelView];
[labelView release];
}
// Get the time zone wrapper for the row
UIImageView *imageView = (UIImageView *)[cell viewWithTag:'ICON'];
imageView.image = NULL;
NSString* extension = [[path pathExtension] lowercaseString];
if ([extension isEqualToString: @"png"] ||
[extension isEqualToString: @"jpg"] ||
[extension isEqualToString: @"jpeg"] ||
[extension isEqualToString: @"bmp"] ||
[extension isEqualToString: @"gif"] ||
[extension isEqualToString: @"tiff"] ||
[extension isEqualToString: @"thm"])
{
NSString *realFilePath = [ fileManager destinationOfSymbolicLinkAtPath:path error:nil ];
if ( realFilePath )
path = realFilePath;
NSURL *url = [[NSURL fileURLWithPath:path] URLByAppendingPathComponent:@"thumb.th"];
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *temp = [manager imageWithURL:url];
if (temp) {
imageView.image = temp;
}
else
{
SDWebImageDownloader *downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self indexPath:indexPath];
}
} else {
imageView.image = [ self determineFileIcon : path ];
}
// Configure the cell.
UILabel *labelView = (UILabel *)[cell viewWithTag:'NAME'];
labelView.text = filename;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
if ( isDirectory ) {
if ( isLink( path ) )
labelView.font = [UIFont italicSystemFontOfSize:16.0];
else
labelView.font = [UIFont boldSystemFontOfSize:16.0];
} else {
if ( isLink( path ) )
labelView.font = [UIFont italicSystemFontOfSize:16.0];
else
labelView.font = [UIFont systemFontOfSize:16.0];
}
labelView = (UILabel *)[cell viewWithTag:'TIME'];
NSCalendar *theCalendar= [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDate *date = [tempDic objectForKey:@"date" ];
NSDateComponents *dateComponents = [theCalendar components:unitFlags fromDate:date];
NSInteger year = [dateComponents year];
NSInteger month = [dateComponents month];
NSInteger day = [dateComponents day];
NSInteger hour = [dateComponents hour];
NSInteger minute = [dateComponents minute];
NSInteger second = [dateComponents second];
[theCalendar release];
labelView.text = [NSString stringWithFormat:@"%d/%02d/%02d %02d:%02d:%02d", year,month,day,hour,minute,second ];
if ( !isDirectory ) {
labelView = (UILabel *)[cell viewWithTag:'SIZE'];
[labelView setHidden:NO];
NSNumber *size = [tempDic objectForKey:@"filesize" ];
float value = [ size floatValue ];
NSString *str;
if ( value > ( 1024*1024 ) ) {
value = value / 1024 / 1024;
str = [NSString stringWithFormat:@"%0.1f MB", value ];
} else if ( value > 1024 ) {
value = value / 1024;
str = [NSString stringWithFormat:@"%0.1f KB", value ];
} else {
str = [NSString stringWithFormat:@"%d Bytes", [ size integerValue ] ];
}
labelView.text = str;
}
else
{
labelView = (UILabel *)[cell viewWithTag:'SIZE'];
[labelView setHidden:YES];
}
[fileManager release];
return cell;
}
添加于 11-17 日:
当“SIGABRT”收到时,documentDirectoryFileList 有对象,例如 30+。接收到的indexPath存在于可见索引路径数组中。但是我注意到:滚动tableview时很容易发生。没有新对象添加到数据源。我所做的只是更新单元格上的图像。
我猜可能是: 当接收到的索引路径开始更新相应的单元格时,我碰巧滚动它并且单元格或索引路径不再可见。然后它崩溃了。
最佳答案
好像是多线程的问题。
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{
@synchronized(tableView)
{
NSArray *arr = [self.tableView indexPathsForVisibleRows];
if ([arr containsObject:indexPath])
{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (!cell)
{
return;
}
UIImageView *imageView = (UIImageView *)[cell viewWithTag:'ICON'];
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *image = [manager imageWithURL:downloader.url];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = image;
});
}
}
}
}
或者你可以
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithIndexPath:(NSIndexPath *)indexPath
{
@synchronized(tableView)
{
NSArray *arr = [self.tableView indexPathsForVisibleRows];
if ([arr containsObject:indexPath])
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationNone];
});//must be in main thread; reloadRowsAtIndexPaths: is not thread safe
}
}
}
关于ios - uitableview更新错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8148811/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
我克隆了一个rails仓库,我现在正尝试捆绑安装背景:OSXElCapitanruby2.2.3p173(2015-08-18修订版51636)[x86_64-darwin15]rails-v在您的Gemfile中列出的或native可用的任何gem源中找不到gem'pg(>=0)ruby'。运行bundleinstall以安装缺少的gem。bundleinstallFetchinggemmetadatafromhttps://rubygems.org/............Fetchingversionmetadatafromhttps://rubygems.org/...Fe
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie