2014-09-17 5 views
1

для моего приложения мне нужно преобразовать некоторый HTML в NSAttributedStrings в tableViews. Это очень интенсивная работа с процессором, поэтому я решил использовать NSCache для эффективного сокращения на этот раз пополам, поскольку HTML конвертируется дважды, один раз для измерения размера ячейки и еще раз для рисования ячейки.NSCache не возвращает данные при первом запросе

Проблема в том, что при первом запросе кеша для объекта он возвращает нуль, как если бы он никогда не отправлялся в кеш.

Оба запроса выполнены в одной и той же очереди (основной), я подтвердил, что кеш-ключ является тем же и что используемый кеш-код является тем же. Что я делаю не так?

Существует мой код:

#import "HITProduct+Cache.h" 

@implementation HITProduct (Cache) 

static NSCache *cache; 

- (NSAttributedString *)attributedString 
{ 
    @synchronized(cache) { 
     if (!cache) { 
      cache = [NSCache new]; 
      cache.evictsObjectsWithDiscardedContent = NO; 
      cache.countLimit = 10; 
     } 
    } 

    NSMutableAttributedString *attributedString; 
    @synchronized(cache) { 
     attributedString = [cache objectForKey:self.title]; 
    } 

    if (!attributedString) { 
     attributedString = [[[NSAttributedString alloc] initWithData:[self.title dataUsingEncoding:self.title.fastestEncoding] options:@{NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType} documentAttributes:nil error:nil] mutableCopy]; //This is very slow 

     @synchronized(cache) { 
      [cache setObject:attributedString forKey:self.title]; 
     } 
    } 

    return [attributedString copy]; 
} 

@end 

ответ

1

Не могли бы вы попробовать этот код (не @synchronized и включен ARC):

- (NSAttributedString *)attributedString { 
    if(self.title == nil){ return nil; } 

    static NSCache *cache = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     cache = [NSCache new]; 
     cache.evictsObjectsWithDiscardedContent = NO; 
     cache.countLimit = 10; 
    }); 


    NSAttributedString *attributedString = [cache objectForKey:self.title]; 
    if (!attributedString) { 
     attributedString = [[NSAttributedString alloc] initWithData:[self.title dataUsingEncoding:self.title.fastestEncoding] 
                  options:@{NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType} 
               documentAttributes:nil error:nil]; 

     [cache setObject:attributedString forKey:self.title]; 
    } 

    return attributedString; 
} 
+0

Спасибо, но [[NSAttributedString Alloc] initWithData еще называют дважды тот же self.title :( –

+0

Можете ли вы попробовать добавить больше журналов, вы уверены, что во второй раз у вас нет, например, пробелов? – Krzysztof

+0

Это тот же самый адрес памяти, я думаю, что коалесцирование строк создаст новый объект для другой строки ? –

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