2012-03-16 9 views
0

지도 (MKMapView)에 점 (MKAnnotationView 's)을로드하는 iOS 앱에서 작업 중이지만 위치가있는 카테고리가 사용 가능한 경우에만 포인트를 켜고 끌 수 있음).배열을 통한 검색을위한 Objective-C의 코드 최적화

JSON을 사용하여 데이터베이스에서 포인트를 가져 와서 오브젝트를 3 개의 배열로 읽습니다. locs는 위치 (이름, ID, 좌표, 설명, 이미지 데이터)의 배열이고, cats는 카테고리 (name , ID, 이미지 데이터)이며 태그는 카테고리 - 위치 쌍 (카테고리 ID & 위치 ID)의 모음입니다.

지도에 점을 추가하려면 위치가있는 범주를 찾은 다음 해당 범주가지도에 있는지 확인하는 몇 가지 루프를 사용하고 있습니다. 문제는 위치를 추가하는 방법이 기기에서 실행될 때 시간이 오래 걸리는 것입니다 (iPhone 4S에서 약 6-10 초). 모든 것을 빠르게 할이 코드를 최적화하는 좋은 방법이 있는지 궁금합니다.

여기 내 코드가 그대로 있습니다. 이 코드는 mapview가로드 될 때마다 실행됩니다. 포인트가지도에 표시 할 수있는 모든 포인트의 배열입니다, shownPoints 활성화 자신의 범주와 모든 점의 배열은 다음과 같습니다

[self.mapView removeAnnotations:points]; 

for (searchLocation *tempLoc in locs) 
{ 
    name = tempLoc.name; 
    description = tempLoc.description; 

    latiString = tempLoc.latiString; 
    longiString = tempLoc.longiString; 

    coordinate.latitude = latiString.doubleValue; 
    coordinate.longitude = longiString.doubleValue; 

    imageData = tempLoc.picture; 

    MapViewAnnotation *destinationPoint = [[MapViewAnnotation alloc] initWithTitle:name andCoordinate:coordinate andDescription:description andImageData:imageData]; 

    [points addObject:destinationPoint]; 

    for (CatTag *tempCatTag in tags) 
    { 
     if ([tempCatTag.locationID isEqualToString: tempLoc.locID]) 
     { 
      for (Category *tempCat in cats) 
      { 
       if ([tempCatTag.categoryID isEqualToString:tempCat.catID] && 
        [[shownCategories objectAtIndex:[cats indexOfObject:tempCat]] isEqualToString: @"YES"]) 
       { 
        [shownPoints addObject: destinationPoint]; 
       } 
      } 
     } 
    } 
} 

[self.mapView addAnnotations:shownPoints]; 

} 당신이 태그에 참여하고있는 것 같습니다

+0

어떤 유형의'locationID' /'locID'와'categoryID' /'catID'입니까? – Costique

+0

'[[NSString stringWithFormat : @ "% @", tempLoc.name] init]'매우 잘못되었습니다. 그냥'tempLoc.name'을 사용하십시오. '[[NSString alloc] initWithFormat : @ "% @", tempCat.catID]'와 동일합니다. – jtbandes

+0

'locationID/locID'와'categoryID/catID'는 모두 NSStrings입니다. 값은 모두 숫자이므로 int로 변환하면 문제가되지 않습니다. –

답변

0

. categoryID == cats.catID 중첩 루프 (N^2, 어쩌면 N^3)를 사용하기 때문에 거기에 objectAtIndex :가 있습니다.

 
NSDictionary *tagsByLocationId = ... 
NSDictionary *catsByCategoryId = ... 

첫 번째는 locationID의 키와 locationID 것을 가지고 태그에있는 모든 CatTags 세트 인 값을 가질 것입니다 : 당신이 있다면 무엇

. catsByCategoryId에 대해서도 마찬가지입니다. 이제

당신 것 :

 
for (CatTags *catTag in [tagsByLocationId objectForKey:tempLoc.locID]) { 
    for (Category *cat in [catsByCategoryId objectForKey:catTag.categoryID]) { 
     if ([shownCategories objectAtIndex:[cats indexOfObject:cat]]) { 
      [shownPoints addObject:destinationPoint]; 
     } 
    } 
} 

일부의 생각 :

  • 에서 [shownCategories가 objectAtIndex : [고양이 indexOfObject : 고양이]]은 NSDictionary와 다른 조회 수
  • 이 있다고 할 수있다 tagsByLocationId 및 catsByCategoryId에는 키당 하나의 값이 있습니다. 코드에서 여러 항목을 허용하므로 일치 항목이있을 때 모두 검색하여 중지하지 않습니다. 그렇다면 인덱스 (tagsByLocationId)를 키 -> 단일 값으로 조정하십시오.

해시 테이블에서 두 개의 직접 조회를 수행하기 때문에 어느 쪽이든 솔루션을 O (1)로 줄일 수 있습니다. 더 빨라야합니다.