gpt4 book ai didi

ios - UICollectionViewCell 的后台线程快照 = WebCore 崩溃

转载 作者:行者123 更新时间:2023-12-01 16:47:35 26 4
gpt4 key购买 nike

我试图解决的最初问题是如何在不阻塞 UI 的情况下截取 UICollectionViewCell 的屏幕截图。我找到了一个解决方案,可用于在后台线程上拍摄给定单元格的快照,唯一的问题是,如果在释放单元格之前未执行快照请求,它会卡在队列中并最终导致崩溃.

[编辑] 我刚刚发现问题与单元格包含 UIWebView 的事实有关。运行以下代码时,我不断收到来自 WebCore 的 EXC_BAD_ACCESS 错误。 当我尝试在没有 UIWebView 的情况下为每个单元格拍摄背景快照时,它工作正常。

谁能确定 UIWebView/WebCore 会导致这个问题和/或我如何解决它?

这是代码:

在我的 UICollectionViewCell 子类中,我创建了一个 NSOperationQueue 的单例实例:

+ (NSOperationQueue*)sharedSnapshotOperation
{
static dispatch_once_t pred;
static NSOperationQueue *shared = nil;
dispatch_once(&pred, ^{
shared = [[NSOperationQueue alloc] init];
shared.name = @"Snapshot Queue";
shared.maxConcurrentOperationCount = 1;
});
return shared;
}

在同一个子类中,我定义了以下用于拍摄快照的方法:
- (void) snapshotAsync:(ImageOutBlock)block
{
CGFloat scaleFactor = [[UIScreen mainScreen] scale];
CGRect frame = self.frame;
__weak CALayer *layer = self.layer;

NSBlockOperation *newBlockOperation = [[NSBlockOperation alloc]init];
[newBlockOperation addExecutionBlock:^{

//TAKE SNAPSHOT OF CELL
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, frame.size.width * scaleFactor, frame.size.height * scaleFactor, 8, frame.size.width * scaleFactor * 4, colorSpace, kCGImageAlphaPremultipliedFirst);
UIGraphicsBeginImageContextWithOptions(frame.size, YES /*opaque*/, scaleFactor);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);

//GET MAIN QUEUE FOR DOING ULTIMATE TASK
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
block(image);
}];
}];

self.blockOperation = newBlockOperation;

//ADD OPERATION TO QUEUE
[[InboxCell sharedSnapshotOperation] addOperation:self.blockOperation];
}

同样,在同一个子类中,我声明了传递给我的异步快照方法的 block :
typedef void(^ImageOutBlock)(UIImage* image);

同样,在同一个子类中,我这样调用上述异步快照方法:
__weak typeof(self) weakSelf = self;
[weakSelf snapshotAsync:^(UIImage* image) {

//PUT THE IMAGE IN THE CACHE (ultimate task)
[weakSelf.delegate setCellScreenShot:image forKey:[weakSelf makeIndexingKeyForScreenShot]];
}];

最后,如果单元格即将被释放(从 UICollectionView 委托(delegate)调用),我尝试取消操作请求:
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell: (UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
InboxCell *inboxCell = (InboxCell *)cell;
[inboxCell.blockOperation cancel];
}

最佳答案

您是否尝试过创建自己的自定义 NSOperation?

这个想法是在您的单元格中保留一个指向 NSOperation 的强指针,该指针将对其进行截图。当您的单元格将被重用(方法 prepareForReuse)或解除分配时,请验证 NSOperation 的状态(isFinished 属性),如果它不只是取消它。

我建议在 UICollectionView 委托(delegate)中创建自己的队列并在其他线程中处理操作。

看看 NSOperation API Doc:
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html

关于ios - UICollectionViewCell 的后台线程快照 = WebCore 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18747767/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com