문제

이메일 주소를 포함하여 웹 API에서 데이터를 끌어내는 iPhone 앱을 만들고 있습니다. 테이블 셀의 각 이메일 주소와 관련된 이미지를 표시하고자하므로 이미지에 대한 주소록을 검색하고 이메일 주소가 책에 없으면 기본값으로 다시 떨어지고 있습니다. 이것은 훌륭하게 작동하지만 몇 가지 우려 사항이 있습니다.

  • 성능: 이메일 주소 (또는 전화 번호)로 주소록 레코드를 찾기 위해 찾은 레시피는보고됩니다. 오히려 느리게. 그 이유는 모든 주소록 기록을 반복해야하며 이미지가있는 각각의 이미지에 대해 모든 이메일 주소를 반복하여 일치를 찾아야하기 때문입니다. 물론 큰 주소록에 시간이 많이 걸릴 수 있습니다.

  • 표 셀: 그래서 나는 이미지를 찾아서 한 번에 모두 찾아야하는 모든 이메일 주소를 모았다고 생각했습니다. 이런 식으로 나는 모든 주소에 대해 한 번만 책을 반복합니다. 그러나 이것은 각 셀이 단일 이메일 주소에 해당하는 테이블 셀에 적합하지 않습니다. 나는 셀을 표시하기 전에 모든 이미지를 수집해야하거나 (잠재적으로 느리게) 각 셀이 각 이미지가로드 될 때 각 이미지를 찾아야합니다 (책을 반복하기 위해서는 더 느리게 각 이메일 주소).

  • 비동기 조회: 그래서 나는 그들을 대량으로 찾아 볼 것이라고 생각했지만 비동기 적으로 NSInvocationOperation. 주소록에있는 각 이미지에 대해 앱 샌드 박스에 축소판을 저장합니다. 그런 다음 각 셀 은이 파일을 참조하고 존재하지 않는 경우 기본값을 표시 할 수 있습니다 (책에 없거나 아직 발견되지 않았기 때문에). 이미지가 나중에 비동기 조회에서 발견되면 다음에 이미지를 표시해야 할 때 갑자기 나타납니다. 이는 이미지의 주기적 재생에 적합 할 수 있습니다 (예 : 주소록에서 이미지가 변경된 경우). 그러나 내 앱의 주어진 인스턴스의 경우 이미지가 실제로 한동안 나타나지 않을 수 있습니다.

  • 비동기 테이블 셀 조회: 이상적으로는 같은 것을 사용할 것입니다 Markjnet의 비동기 테이블 셀 업데이트 이미지가 다운로드 된 후에 테이블 셀을 업데이트합니다. 그러나 이것이 작동하기 위해서는 NSInvocationOperation 각 셀에 대한 작업이 표시되고 캐시 된 아이콘이 샌드 박스에서 누락 된 경우. 그러나 우리는 각각의 주소록 전체를 통해 비효율적으로 반복되는 것으로 돌아 왔으며, 새로운 이메일 주소를 방금 다운로드 한 경우 많은 일이 될 수 있습니다.

그래서 내 질문은 : 다른 사람들은 어떻게 이것을합니까? 나는 tweetie2와 함께 고민하고 있었고, 표현 된 테이블 셀을 비동기 적으로 업데이트 한 것처럼 보입니다. 필요한 모든 이미지에 대해 별도의 HTTP 요청을 보내고 있다고 가정합니다. 그렇다면 이메일 주소로 로컬 주소록을 검색하는 것이 덜 효율적이지 않다고 생각합니다. 아마도 그것이 최선의 방법일까요? 주소록 검색과 관련된 성능 문제에 대해 걱정하지 않습니까?

그렇다면 샌드 박스에 축소판 이미지를 저장하는 것이 캐싱에 가장 적합한 접근 방식입니까? 그리고 주소록이 하루에 한 번 변경 사항으로 모든 썸네일을 업데이트하기 위해 새 작업을 만들고 싶다면 하루에 한 번 말하기 가장 좋은 방법은 무엇입니까?

나머지는 어떻게 이런 종류의 문제를 해결합니까? 제안은 대단히 감사하겠습니다!

도움이 되었습니까?

해결책

이미지의 실제 캐싱에 어떤 전략을 사용하든 가능하면 전자 메일 주소를 배치 할 때마다 주소록 데이터를 통과 할 수 있습니다. (그렇습니다. 나는 이것을 비동기 적으로 할 것입니다.)

검색 결과를위한 메모리 내 캐시 역할을하는 nsmutabledictionary를 만듭니다. 다운로드의 각 이메일 주소 로이 사전을 키로 키로 초기화하고, 해당 키의 값 (예 : Sentinel)을 사용하십시오. [NSNull null]).

다음으로 주소록에서 각 Abrecordref를 통해 ABRecordCopyValue(record, kABPersonEmailProperty) 그리고 반환되는 각 abmultivalue의 결과를 통한 루프. 이메일 주소가 캐시의 키 인 경우 [NSNumber numberWithInt:ABRecordGetRecordId(record)] 사전에서 그 키의 값으로.

이 사전을 조회 인덱스로 사용하면 Hoopjones의 답변에 제안 된 바와 같이 사용자의 현재 스크롤 위치가 주어지면 현재 테이블보기에 표시중인 이메일 주소에 대해서만 AbrecordRefs의 이미지를 빠르게 얻을 수 있습니다. 주소록 변경 리스너를 추가하여 캐시를 무효화하고 다른 인덱싱 작업을 트리거 한 다음 해당 수준의 "최신"이 필요한 경우보기를 업데이트 할 수 있습니다.

다른 팁

마지막으로 나열된 방법 (비동기 테이블 셀 조회)을 사용하지만 현재 레코드가 표시되는 이미지 만 보입니다. UiscrollViewDelegate 메소드를 과부하하여 사용자가 스크롤을 중지했을 때를 찾은 다음 현재 가시 셀에 대한 요청 만 시작합니다.

이와 같은 것 (이것은 내가 지금 찾을 수없는 웹에서 찾은 튜토리얼에서 약간 수정되었습니다. 저자를 인용하지 않은 것에 대한 사과) :

- (void)loadContentForVisibleCells
{
    NSArray *cells = [self.table visibleCells];
    [cells retain];
    for (int i = 0; i < [cells count]; i++) 
    { 
        // Go through each cell in the array and call its loadContent method if it responds to it.
        AddressRecordTableCell *addressTableCell = (AddressRecordTableCell *)[[cells objectAtIndex: i] retain];
        [addressTableCell loadImage];
        [addressTableCell release];
        addressTableCell = nil;
    }
    [cells release];
}


- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView; 
{
    // Method is called when the decelerating comes to a stop.
    // Pass visible cells to the cell loading function. If possible change 
    // scrollView to a pointer to your table cell to avoid compiler warnings
    [self loadContentForVisibleCells]; 
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
    if (!decelerate) 
    {
       [self loadContentForVisibleCells]; 
    }
}

현재 어떤 주소 레코드가 보이는지 알면, 그 주소를 검색하는 것만 (5-7 레코드)를 검색하는 것이 빠르게 번개가 될 것입니다. 일단 이미지를 잡으면 사전으로 캐시하여 나중에 이미지 요청을 다시 할 필요가 없습니다.

UitableView에서 게으른 이미지로드를 구현하려고 시도하는 것 같습니다. Apple의 좋은 예가 있습니다. 여기에 참조하고 있습니다.uitableview의 게으른 부하 이미지

참고로, 나는 비동기 이미지 로딩 및 빠른 파일 캐싱을 수행하기위한 무료, 강력하고 쉬운 라이브러리를 출시했습니다 : HJ 관리 객체http://www.markj.net/asynchronous-loading-caching-images-iphone-hjobjman/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top