Проблема в том, что я управляю scrollView с большим количеством плиток.Каждое видимое изображение мозаичного изображения загружается из URL или (после первой загрузки URL) из кэшированного файла в фоновом режиме.Невидимые плитки перезаписываются (задайте новый кадр и перерисовку).
Загрузка изображения зависит от положения плитки.
При прокрутке на большие расстояния для каждой плитки требуется несколько перерисовок: каждая плитка загружается (и отображается)несколько раз перед тем, как отобразить правильное изображениеи перед добавлением новой операции я отменил все операции для той же плитки:
-(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: isCancelled при выполнении:> отменить метод loadImage для:>
Так что отмена работы.
Теперь я сохраняю ссылку на последнюю операцию в объекте TileView и выполняю операцию setImage, только если вызванная операция равна операции TileView.
Не имеет значения ...
Похоже, есть количество операций для загрузки разных изображений в одну плитку, вызванную одну за другой.
Есть еще какие-нибудь предложения?
Для очистки:
Есть синглтонный 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
Большое спасибо за любая помощь!
РЕШЕНИЕ:
Из ответа ниже: необходимо создать подкласс NSOperation
Поскольку я создаю подкласс NSOperation и помещаю всеloadImage: вставьте в него «основной» метод (просто переместите весь код сюда и ничего больше) и все работает просто отлично!
Как и в случае задержки прокрутки: это происходит из-за загрузки изображений в UIImageView (это занимает много времени из-зараспаковать и растеризовать (как я понял).
Так что лучше использовать CATiledLayer. Он загружает данные в фоновом режиме и делает это намного быстрее.