问题是我管理的scrollView中有很多tile。 每个可见的图块显示图像都从URL加载或(在第一个URL加载后)在后台加载缓存文件。隐形瓷砖回收(设置新框架和重绘)。NSOperationQueue取消特定操作
图像加载取决于图块位置。
通过长距离滚动,每个图块都有多次重绘:每个图块在显示正确的图块之前先加载(并显示)不同的图像几次。
所以问题是在添加新之前取消所有以前添加的瓦片操作。
我继承NSInvocationOperation只是包含上下文对象检测连接到操作和之前添加新的操作我取消了,相同的瓦片全部操作:
-(void)loadWithColler:(TileView *)coller {
if (queue == nil) {
queue = [NSOperationQueue new];
}
NSInvocationOperationWithContext *loadImageOp = [NSInvocationOperationWithContext alloc];
[loadImageOp initWithTarget:self selector:@selector(loadImage:) object:loadImageOp];
[loadImageOp setContext:coller];
[queue setSuspended:YES];
NSArray *opers = [queue operations];
for (NSInvocationOperationWithContext *nextOperation in opers) {
if ([nextOperation context] == coller) {
[nextOperation cancel];
}
}
[queue addOperation:loadImageOp];
[queue setSuspended:NO];
[loadImageOp release];
}
而且在操作本身我检查isCancelled:
-(void)loadImage:(NSInvocationOperationWithContext *)operation {
if (operation.isCancelled) return;
TileView *coller = [operation context];
/* TRY TO GET FILE FROM CACHE */
if (operation.isCancelled) return;
if (data) {
/* INIT WITH DATA IF LOADED */
} else {
/* LOAD FILE FROM URL AND CACHE IT */
}
if (operation.isCancelled) return;
NSInvocationOperation *setImageOp = [[NSInvocationOperation alloc] initWithTarget:coller selector:@selector(setImage:) object:cachedImage];
[[NSOperationQueue mainQueue] addOperation:setImageOp];
[setImageOp release];
}
但它什么都不做。有些时候,早期回报有效,但瓷砖在正确之前仍会加载许多图像。
那么我怎么能成功? 当滚动时,这些不需要的操作会导致主线程延迟吗? (因为延迟是存在的,我不知道为什么......在后台所有负载..)
更新:
随着的NSLog: > 取消的LoadImage方法: 在执行isCancelled: >
因此取消工作。
现在我保存对TileView对象中上次操作的引用,并且只有在调用的操作等于TileView操作时才执行setImage操作。
没有任何区别...
貌似有操作的次数,以不同的图像加载到一个瓷砖调用此起彼伏。
还有其他建议吗?
过关:
有单身的DataLoader(从它的所有代码)。和所有的瓷砖已经打电话给它drowRect:
[[DataLoader sharedDataLoader] loadWithColler:self];
更新:
NSInvocationOperation子类:
@interface NSInvocationOperationWithContext : NSInvocationOperation {
id context;
}
@property (nonatomic,retain,readwrite) id context;
@end
@implementation NSInvocationOperationWithContext
@synthesize context;
- (void)dealloc
{
[context release];
[super dealloc];
}
@end
非常感谢任何帮助!
SOLUTION:
从回答如下:需要从的NSOperation
子类当我子类的NSOperation,并把所有的LoadImage:代码到它的“主”的方法(只是将所有代码在这里,没有别的),所有的工作都很完美!
随着对滚动延迟:它发生的原因加载图像到UIImageView的(需要很长的时间,因为解压缩和光栅化的(我的理解)
因此,更好的办法是使用CATiledLayer它在后台加载数据和。做得更快
但即使从缓存文件加载数据并且根本不使用网络,也会出现缓慢滚动。在特定线程中的所有数据加载管理NSOperationQueue。如果我将从NSOperation子类创建另一个新线程,它可以帮助吗? – 2012-03-17 12:44:12
可能有太多的线程...尝试设置队列中并发操作的最大数量,看看发生了什么 – Andrea 2012-03-17 18:09:49
忘了说也尝试使用核心动画工具和时间分析器来检查性能,看看是否有长时间操作。 – Andrea 2012-03-17 18:11:14