Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios tableview中的单元格滚动不顺畅_Ios_Iphone_Objective C_Ios7 - Fatal编程技术网

Ios tableview中的单元格滚动不顺畅

Ios tableview中的单元格滚动不顺畅,ios,iphone,objective-c,ios7,Ios,Iphone,Objective C,Ios7,我几乎完成了我的应用程序的编码,但我仍然有一个问题,我无法解决几个星期…我浏览了这个网站和其他网站上的同一个问题,但我找不到解决它的方法。 我有一个表格视图,其中包含从服务器下载的图像的单元格(如Instagram)。我的问题是当我滚动表格视图时,它不是平滑的并且会闪烁 要构造表视图,请执行以下操作: -标题视图和单元格都是子类。 -我异步下载所有图像,然后将它们缓存在我应用程序的tmp文件夹中(每个大约25Ko)。 -下载的每个图像都具有与UIImageView相同的帧,应将其放置在其中。 -

我几乎完成了我的应用程序的编码,但我仍然有一个问题,我无法解决几个星期…我浏览了这个网站和其他网站上的同一个问题,但我找不到解决它的方法。 我有一个表格视图,其中包含从服务器下载的图像的单元格(如Instagram)。我的问题是当我滚动表格视图时,它不是平滑的并且会闪烁

要构造表视图,请执行以下操作:

-标题视图和单元格都是子类。 -我异步下载所有图像,然后将它们缓存在我应用程序的tmp文件夹中(每个大约25Ko)。 -下载的每个图像都具有与UIImageView相同的帧,应将其放置在其中。 -我试图以png和jpeg格式保存图像,但问题仍然存在

我做了另一个测试,没有把下载的图像放在单元格里,而是把一个图像放在我的应用程序里(可以任意缩放)。在这种情况下,表视图将平滑滚动

所以我怀疑问题可能在于我缓存图像并从缓存中获取它们的方式。但即使在这种情况下,我也尝试使用NSCache和临时文件夹缓存图像,但没有结果

这是我的密码:

-(void)CacheTheImageDownloaded: (NSData *)TheImageData : (NSString*)PathOfImage{

   NSFileHandle *fout;
   [[NSFileManager defaultManager] createFileAtPath:PathOfImage contents:Nil   attributes:Nil];
   fout = [NSFileHandle fileHandleForWritingAtPath:PathOfImage];
   [fout writeData:TheImageData ];
   [fout closeFile];

}


-(UIImage*)GetTheImageFromTemporaryDirectory:(NSString*)ImagePath{
   UIImage *theCachedImage;
   theCachedImage = [UIImage imageWithContentsOfFile:ImagePath];
   return theCachedImage;
}


-(void)GetImageForTheViewedCell: (NSString*) ImageName : (NSString*)TheImageURL :    (NSInteger)therow : (UIImageView*)MyImageView {

  NSString *TheKey = [NSString stringWithFormat:@"%ld", (long)therow];
  NSString *tmpDir = NSTemporaryDirectory();
  NSString *ImageDownloadedTmpDir;
  ImageDownloadedTmpDir = [tmpDir stringByAppendingPathComponent:@"TMPImagesDownloaded"];

  NSMutableString *TheImagePath = [NSMutableString stringWithString:ImageDownloadedTmpDir];
  [TheImagePath appendString:@"/"];
  [TheImagePath appendString:ImageName ];

if ( [self VerifyIfImageIsAlreadyCached:TheImagePath]){
    MyImageView.image = [self GetTheImageFromTemporaryDirectory:TheImagePath];
}
else{
    NSBlockOperation *loadImageIntoCellOp = [[NSBlockOperation alloc] init];
    [loadImageIntoCellOp addExecutionBlock:^(void){
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),  ^{
            NSURL *theURL = [NSURL URLWithString:TheImageURL];
            NSData *data1 = [NSData dataWithContentsOfURL:theURL ];
            NSData *data = UIImagePNGRepresentation([UIImage imageWithData:data1]);
            dispatch_sync(dispatch_get_main_queue(), ^{
                MyImageView.image = [UIImage imageWithData:data];
                NSBlockOperation *ongoingDownloadOperation =       [self.TheImageDownloadOperations objectForKey:TheKey];
                if (ongoingDownloadOperation) {
                    [self.TheImageDownloadOperations removeObjectForKey:TheKey];
                }
                [self CacheTheImageDownloaded:data :TheImagePath];
            });
        });
    }];

    if (TheKey) {
        [self.TheImageDownloadOperations setObject:loadImageIntoCellOp forKey:TheKey];
    }

    if (loadImageIntoCellOp) {
        [self.imageLoadingOperationQueue addOperation:loadImageIntoCellOp];
    }

}


}
我正在使用Xcode 5.02

谢谢你的建议

编辑

以下是我的CellForRowatineXpath代码:

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


 static NSString *cellIdentifier = @"myCustomCell";
 MyCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 if (cell == nil){
     cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
 }
[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

NSInteger row = indexPath.row;
cell.tag = row ;

//The Profile picture
NSString *theurl = self.myProfilePics[row];
NSString *TheImageName = self.TheImageNames[row];
[self GetImageForTheViewedCell:TheImageName:theurl:row: cell.ProfilePicView];  //getting image from the cache or downloaded async
[cell.TheProfilePicButton setBackgroundImage:cell.ProfilePicView.image forState:UIControlStateNormal];
[cell.contentView addSubview: cell.TheProfilePicButton];

//Username:
NSString *myusername = self.Usernames[row];
[cell.UsernameButton setTitle: myusername forState:UIControlStateNormal];
[cell.contentView addSubview:cell.UsernameButton];

//date
NSString *mydate =  self.Dates[row];
[cell.DateLabel setText: mydate];
[cell.contentView addSubview: cell.DateLabel];

return cell;

}

你说“我试图以png和jpeg格式保存图像”。我想,您只是“保存到缓存”图像。您可以在tableview中使用
UIImagePNGRepresentation

当您加载许多图像时,UITableView的性能非常低,即使您实现了“延迟加载”

因此,我的答案是您应该使用
uiimagejpegresentation
代替
UIImagePNGRepresentation

编辑

使用UIGraphicsGetImageFromCurrentImageContext如何

UIImage *image = [UIImage imageWithContentsOfFile:filePath];
CGSize imageSize = image.size;
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
[image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
还有一点,NSCache如何提高性能。这是一个样本

@inteface YourTableViewController ()
@property (nonatomic) NSCache *cache;
@end

@implemetation YourTableViewController

.
.
.

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = @"Cell";
    YourCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[YourCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.yourImageView.frame = CGRectMake((self.frame.size.width - self.rowHeight)*0.5f, 0, self.rowHeight, self.rowHeight);
    }
    [cell.imageView setImage:nil];
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_async(globalQueue, ^(){

        UIImage *image = [self.cache objectForKey:filePath];
        if (image == nil) {
            image = [UIImage imageWithContentsOfFile:filePath];
            CGSize imageSize = image.size;
            UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
            [image drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
            image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
            [self.cache setObject:image forKey:filePath];
        }

        dispatch_async(mainQueue, ^(){
            if ([[tableView indexPathsForVisibleRows] containsObject:indexPath]) {
                YourCell *cell = (YourCell *)[tableView cellForRowAtIndexPath:indexPath];
                if(image) {
                    [cell.yourImageView setImage:image];
                }
            }
        });
    });
    return cell;
}

.
.
.

@end

你能试着把这一行从
主队列中放出来吗<代码>[自缓存图像下载:数据:图像路径]是的,我会试试。但是,由于每个单元格只调用一次该方法,当我上下滚动多次表视图时,问题应该消失了。你不这么认为吗?我刚试过,从缓存中获取图像时也这么做了…问题仍然存在…:/同时确保单元格中的元素/层都没有使用clipToBounds,这是一个性能杀手I不使用单元格的clipToBounds。单元格中的所有元素都是在UItableViewCell类中创建的,并使用cell.contentview添加子视图:功能所有下载的图像都是用户在应用程序上拍摄的图像,因此我尝试在将它们上载到服务器之前以jpeg和png格式保存它们。我更喜欢UIImageJPEGresentation,因为我可以控制质量,并减少每个图像的重量。您能在UIViewController中显示-cellForRowAtIndexPath:吗?谢谢并
[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]看起来很糟糕。不应删除和重新添加子视图
UITableView
重用子视图而不进行分配,只将内容放在分配的视图上。这是因为
UITableView
的工作速度很快。我认为,您应该在
自定义UITableViewCell
中实现
[cell.contentView addSubview:subview]
,谢谢您的建议!不幸的是,这并没有解决问题:(谢谢!我将尝试按您建议的方式缓存它们。我会在尝试后立即回复您!