2013-12-26 6 views
0

Я пытаюсь преобразовать этот код, чтобы сделать цикл for на фоновом потоке, потому что он очень медленный и лаги, как есть.IOS dispatch_async и для цикла

-(void)prepareLayout { 
    [super prepareLayout]; 

    if (!_animator) { 
    _animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; 
    CGSize contentSize = [self collectionViewContentSize]; 
    NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)]; 
      for (UICollectionViewLayoutAttributes *item in items) { 
        UIAttachmentBehavior *spring = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center]; 

        spring.length = 0; 
        spring.damping = self.springDamping; 
        spring.frequency = self.springFrequency; 

        [_animator addBehavior:spring]; 

      } 
} 

}

Я попробовать это, но он не работает должным образом ... Он избавляется от лага, но некоторые строки отсутствуют или странные позиции в представлении коллекции я Thats сог для петля не работает должным образом с отправкой ... - (void) prepareLayout { [super prepareLayout];

if (!_animator) { 
    _animator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self]; 
    CGSize contentSize = [self collectionViewContentSize]; 
    NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)]; 

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
      for (UICollectionViewLayoutAttributes *item in items) { 
        UIAttachmentBehavior *spring = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center]; 

        spring.length = 0; 
        spring.damping = self.springDamping; 
        spring.frequency = self.springFrequency; 

        [_animator addBehavior:spring]; 
      } 

      dispatch_sync(dispatch_get_main_queue(), ^{ 

      }); 
     }); 
    } 
} 

Я пробовал другие варианты, но не мог заставить его работать ... было бы здорово, если бы кто-то может помочь мне преобразовать этот код, чтобы работать в фоновом потоке должным образом ... спасибо

+0

Я думаю, что addBehavior: должно выполняться в главной очереди(). Попробуйте сделать addBehavior: на главной очереди с диспетчером sync() – nkongara

+0

Привет :) спасибо, я попробовал это, но потом это вообще не работает ... Я думаю, это потому, что тогда цикл вызывается несколько раз, но addBehavior: будет только вызывается один раз в конце очереди ... В представлении коллекции ничего не отображается. Прямо сейчас с кодом отправки, который я опубликовал, он работает без запаздывания, но строки находятся в странных позициях ... возможно, потому, что addBehavior: нужно запускать в главной очереди ... но как вы запускаете основную очередь для каждого цикла ... – user3135618

+0

dispatch_sync (dispatch_get_main_queue(),^{ [_animator addBehavior: spring]; }); – nkongara

ответ

0

Нет ни одной части вашего prepareLayout, которая может быть надежно помещена в фоновый поток. Элементы UIKit должны быть доступны только в основном потоке.

prepareLayout не следует вызывать достаточно часто, чтобы он мог вызвать ваше отставание. Если его вызывают очень часто, вам нужно понять, почему ваш макет так часто недействителен.

Если ваш вид коллекции очень большой (например, сотни предметов), то ваша проблема, вероятно, связана с тем, что вы слишком много предметов занимаетесь поведением. Вы должны прикреплять элементы к поведению по мере их создания и удалять их по мере их удаления. UIKit Dynamics не предназначена для управления сотнями или тысячами элементов.

Обязательно просмотрите Advanced Techniques with UIKit Dynamics от WWDC 2013. Я обнаружил, что объединение UICollectionView и UIKit Dynamics не является очевидным (начало страницы 110 в слайдовой колоде). Если вы не переопределяете layoutAttributesForElementsInRect:, тогда не забудьте обратить внимание на это обсуждение.

Смежные вопросы