2015-01-02 2 views
0

largish (5000 항목) JSON 파일의 이미지와 텍스트를 표시 할 셀이있는 UITableView이 있습니다. JSON을 스트리밍하고 UITableView을 즉시 업데이트하기를 원합니다.하지만 배관을 해결할 수 없습니다.Objective-C iOS : JSON 스트림에서 즉시 UITableView 채우기 시작

- (NSArray *)parseJSONIntoImageObjectsFromData:(NSData *)rawJSONData { 
    NSError *error; 
    NSMutableArray *arrayOfImageObjects = [[NSMutableArray alloc] init]; 
    NSURL *myURL = [[NSURL alloc] initWithString:self.urlString]; 
    NSData *objects = [NSData dataWithContentsOfURL:myURL]; 
    NSInputStream *stream = [[NSInputStream alloc] initWithData:objects]; 
    [stream open]; 

    NSMutableArray *arrayFromStream = [NSJSONSerialization JSONObjectWithStream:stream options:NSJSONReadingAllowFragments error:&error]; 

    for (NSDictionary *JSonDictionary in arrayFromStream) { 
    NSLog(@"Count is %lu", (unsigned long)arrayOfImageObjects.count); 
    NSInteger imgID = (NSInteger)JSonDictionary[@"id"]; 
    ImageObject *newImageObject = [[ImageObject alloc] initWithID:imgID andTitle:JSonDictionary[@"title"] andThumbnailURL:JSonDictionary[@"thumbnailUrl"]]; 
    [arrayOfImageObjects addObject:newImageObject]; 
    } 
    return arrayOfImageObjects; 
} 

디버그 창에 NSLog이 나타나므로 확실히 스트림으로 가져옵니다. 그러나 반환을 기다리기 때문에 완료해야합니다. 나는 이것에 대해 조금 당황하고 좋은 코드 샘플을 찾을 수 없다. 아마도 스트림을 반환합니까?

EDIT : 내가 발생하는 간단한 지연에 대해 크게 우려하지 않고 있으며, 지연이 구문 분석보다 검색에 더 많은 것이라고 확신합니다. 단지 스트림과 업데이트로 데이터를 검색하는 방법을 배우고 싶습니다. 이 방법을 개선하기 위해 점진적으로 UITableView을 사용하십시오. 데이터 검색 및 조작 작업을 즐기며 더 많이 알면 내 기술을 향상 시키려고합니다.

또한 이미지는 표시 시간에 NSOperationQueue을 사용하여 비동기 적으로 검색되며이 작업에는 별 문제가되지 않습니다.

+0

이것은 가치있는 최적화 일 수 있지만 5000 JSON 객체를 구문 분석하는 데 걸리는 시간을 측정 했습니까? JSON 객체 자체가 너무 크지 않으면 무시할 정도로 오래 걸릴 것입니다. – MaxGabriel

+0

@MaxGabriel 다운로드와 구문 분석에 약 5 초가 걸리지 만, 전혀 나쁘지는 않지만 배울 점이 있습니다. –

+0

데이터를 "페이징"하는 것도 고려할 수 있습니다. 따라서 한 번에 100 개 개체 만 가져오고 (API로 해당 능력을 가진 경우) tableView : willDisplayCell : forRowAtIndexPath와 같은 것을 사용하여 다음 개체 집합을로드 할시기를 결정합니다. – Fraggle

답변

1

이 메서드 외부에서 속성 또는 변수로 NSMutableArray *arrayOfImageObjects을 정의한 다음 for 루프에서 100 개 개체마다 [self.tableView reloadData]를 호출하십시오.

numberOfRowsInSection이 arrayOfImageObjects를 키잉한다고 가정하고 cellForRowAtIndexPath가이를 사용하여 테이블 데이터를 채우는 것으로 가정합니다.

또한 데이터를 '페이징'하여 한 번에 50 개 정도의 개체 만로드 할 수 있습니다 (API에서 'http://example.com/imagedata?page=1'과 같이 지원한다고 가정). 그런 다음 사용자가 테이블 뷰를 쓸어 넘기거나 스크롤하면 다른 API 호출을 수행하여 페이지 번호를 늘리고 새로운 데이터 세트를 현재 세트에 추가하고 reloadData를 호출 할 수 있습니다.

EDIT : 또한 "parseJSONIntoImageObjectsFromData"가 비동기 적으로 실행되고 있다고 가정합니다. 그렇지 않으면 AFNetworking (또는 sendAsynchronousRequest : queue : completionHandler : NSURLConnection)과 같은 것을 사용하고 완료 블록에서 배열에 추가를 시작할 수 있습니다.

+0

감사합니다. 내가 사용하고있는 API가이를 사용하지 않거나 사용했을 것입니다. 나는 이것을 내일 시도 할 것이다, 그것은 흥미있는 소리가 난다. 도움에 감사드립니다. –

+0

그리고 parse 함수는 비동기 대기열에서 호출됩니다. –

2

벤치마킹하면 JSON의 구문 분석 시간이 중요하지 않음을 알게 될 것입니다. 느린 부분은 원래 JSON (아마도 ImageObject 개체 생성)의 다운로드가 될 것입니다. Instruments에서 이것을 벤치마킹해야하며 ("시간 프로파일 러"도구 사용) "레코드 대기 스레드"옵션을 사용하십시오. 인스트루먼트를 사용하여 이러한 종류의 문제를 진단하는 방법에 대한 데모는 WWDC 비디오 Building Concurrent User Interfaces on iOS을 참조하십시오.

나는 동 기적으로 실행되므로 dataWithContentsOfURL을 먼저 퇴장시킵니다. NSURLSession 메서드 dataWithURL과 같은 비동기 기술을 사용하는 것이 좋습니다 (또는 iOS 7 이전 버전에 대한 지원이 필요하면 NSURLConnection 메서드 sendAsynchronousRequest).

이러한 경우 일반적으로 JSON은 작아서 가장 큰 지연은 초기 요청을 할 때 네트워크 대기 시간에 기인합니다. 나는 이것이 당신이 페이징/스트리밍 접근법에 대한 코드의 주요 리팩토링에 착수하지 않도록하면서 이것이 문제를 해결할 것임을 확인하지 않는다는 것을 언급한다.

또한이 ImageObject 로직을 공유하지 않았지만 이미지를 동 기적으로로드하는 경우 비동기 검색을위한 리팩토링을 할 가능성이 높습니다.그 수업에 대해 더 많이 알지 못하면 그 점에 관해 더 이상 당신에게 조언하기가 어렵습니다.

+0

감사합니다. 나는 원래'NSURLSession' 메쏘드'dataWithURL'를 사용하여 데이터를 얻은 다음 그것을 파싱했지만,'dataWithContentsOfURL'을 사용하는 것에 대한 과거 참조를 발견하고 스트림이 작동 하는지를보고 싶었습니다. NSURLSession'에서 더 많은 것을 둘러보고 내가 찾을 수있는 것을 보겠습니다. 이미지는 'NSOperationsQueue'와 로컬 캐시 인 btw를 통해 요청에 따라 비동기 적으로 검색됩니다. 이것은'NSURLSession'과'NSJSONSerialization' 프레임 워크에 대한 친숙 함을 향상시키기위한 개인 프로젝트입니다. 리팩토링은 그곳에있는 것입니다. –

+0

난 당신이 스트림을하려고했는지 상상할 수 (당신은 당신이 최소한의 메모리 풋 프린트, 그것을 해석으로, 영구 저장소에 직접 콘텐츠를 스트리밍, 정말 큰 XML과 함께 사용할 수있는 기술이다)하지만, 달성하지 않을 것이다 JSON을 가진 모든 것. 성공할 기회를 얻으려면'libxml' 또는'NSXMLParser'와 같은 델리게이트 기반 파서가 필요합니다. – Rob