2014-09-17 3 views
1

내 앱에 대해 tableViews의 NSAttributedStrings로 일부 HTML을 변환해야합니다. 이것은 매우 CPU 집약적 인 작업이므로 NSCache를 사용하여 HTML이 두 번 변환 되었기 때문에 한 번에 셀 크기를 측정하고 한 번 더 셀을 그리기 때문에이 시간을 효과적으로 반으로 줄이기로 결정했습니다.NSCache가 처음으로 데이터를 반환하지 않습니다.

문제는 캐시가 객체에 대해 처음으로 쿼리되면 캐시로 전송 된 적이없는 것처럼 nil을 반환한다는 것입니다.

두 요청이 동일한 대기열 (주)에서 만들어 지므로 캐시 키가 동일하고 사용중인 캐시가 동일하다는 것을 확인했습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

#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

는이 코드를 시도 할 수 없습니다 (NO @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

정확히 동일한 메모리 주소입니다. 문자열 병합은 다른 문자열에 대한 새 개체를 만들 것이라고 생각합니다. ? –

관련 문제