Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Программирование iOS/iPhone

Войти
Регистрация
Восстановить пароль
 
 
albert102
-21 / 1 / 0
Регистрация: 30.10.2013
Сообщений: 53
#1

Карта Apple подтормаживает при прокрутке - Программирование iOS

19.05.2014, 00:04. Просмотров 759. Ответов 16
Метки нет (Все метки)

Дорогие друзья, доброй ночи!

использую компонент MkMapView, добавляю на карту 20 картинок (аннотации 60x60 пикселей по 12 кб каждая) и при прокрутке влево-вправо-вверх-вниз карта начинает тормозить. Неприятно.

Подскажите, пожалуйста, как можно уменьшить подтормаживание карты или избавиться вообще?

Заранее спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.05.2014, 00:04
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Карта Apple подтормаживает при прокрутке (Программирование iOS):

Интерактивная карта / псевдо карта - Objective-C
Всем добрый день. Столкнулся с проблемой построения интерактивной карти. Просмотреть такую карту можно на этом сайте - это границы...

Apple iPhone 4s (8.1.3) требует ввести Apple ID и пароль при включении телефона - iPhone
В общем попал ко мне айфон 4эс и требовал ввести пароль, а в верхней строчке было написано мыло старого владельца, но пароль я естественно...

Подтормаживает при загрузке с торрентов - Windows 7
INFO: Motherboad: Gigabyte GA-870A-USB 3L Processor: AMD Athlon II X3 455 Cooler: Glacial Tech Igloo 5610 Plus PWM Video card:...

Подтормаживает картинка при записи с экрана - Видеопрограммы
Здравствуйте! Поставил вчера Camtasia Studio 7. Пробовал записывать видео, тестировал на клипе с обычного сайта. При просмотре...

Подтормаживает мышь при резких движениях в играх.Стим - Windows 7
Заранее извиняюсь,если написал не туда. Тема вот в чем.Я играю в CS:GO,проблема в том,что когда я резко дергаю мышь(например слева на...

Компьютер подтормаживает и при включении открывается сайт nftds2.ru - Удаление вирусов
Компьютер подтормаживает и при включении открывается сайт nftds2.ru, переадресовывает на рекламные сайты, так же компьютер подтормаживает...

16
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
19.05.2014, 07:54 #2
albert102, каким образом добавляете?
Покажите код, будет проще вам помочь.
0
albert102
-21 / 1 / 0
Регистрация: 30.10.2013
Сообщений: 53
19.05.2014, 08:19  [ТС] #3
делаю так

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
    
    
    if([annotation isKindOfClass:[PlaceMark class]]){
        MKAnnotationView *annotationView=[myMapView dequeueReusableAnnotationViewWithIdentifier:nil];
        
        if(annotationView == nil){
            annotationView=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
            annotationView.enabled = YES;
            
            // +++ получаем ID юзера из title и формируем ссылку +++
            
            NSString * getID = [annotationView.annotation title];
            NSString * link = [NSString stringWithFormat:@"http://мойсайт.ru/gallery/%@/image.jpg", getID];
            
            
            // +++ загружаем аватарку в отдельном потоке +++
            
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                UIImage * image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:link]]];
                dispatch_async(dispatch_get_main_queue(), ^{
                    
                    // как только аватарка загрузится, применяем ее к аннотации
                    annotationView.image = image;
                    
                    
                });
            });
            
        }
        return annotationView;
    }
    return nil;
}

placeMark это у меня отдельный класс, с помощью него я добавляю к аннотации ее координаты, заголовок (в который id юзера закладываю) и подзаголовок (с возрастом юзера). вызываю событие addAnnotation в цикле (получаю с сервера массив юзеров и по очереди добавляю их на карту)

Objective-C
1
2
3
4
5
 placeMark = [[PlaceMark alloc]
                     initWithCoordinate:CLLocationCoordinate2DMake(s_lat, s_long)
                     andMarkTitle:s_userID
                     andMarkSubTitle:s_friend];
        [myMapView addAnnotation:placeMark];
Добавлено через 6 минут
когда на карту добавляю 5-10 аватарок, все пока что нормально, но после 15-20 начинает тормозить. представляю как будет тормозить если будет 50-100 аватарок.
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
19.05.2014, 08:43 #4
Цитата Сообщение от albert102 Посмотреть сообщение
annotationView=[myMapView dequeueReusableAnnotationViewWithIdentifier:nil];
if(annotationView == nil){
Identifier используйте, чтобы переиспользуемость была, alloc дорогостоящая операция, незнаю что там в init еще.

Дальше:
Аватарки лучше загружать в вашем классе PlaceMark внутри. Ибо если вы будете делать так:
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
if (annotationView == nil) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                UIImage * image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:link]]];
                dispatch_async(dispatch_get_main_queue(), ^{
                    
                    // как только аватарка загрузится, применяем ее к аннотации
                    annotationView.image = image;
                    
                    
                });
            });
}
и annotationView будет != nil - у вас аватарка будет неправильно выставлена.

Сделайте метод с блоком по типу:
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
- (UIImage *)avatarImageWithCompletion:(void(^)(UIImage *image, NSError *error))completion {
    if (self.avatarImage) {
        return self.avatarImage;
    } else {
        if (!self.downloading) {
            self.downloading = YES;
            __typeof(self) wThis = self;
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                UIImage * image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:link]]];
                dispatch_async(dispatch_get_main_queue(), ^{
                    __typeof(wThis) sThis = wThis;
                    sThis.downloading = NO;
                    if (image) {
                        sThis.avatarImage= image;
                        completion(sThis.avatarImage, nil);
                    } else {
                        completion(nil, [NSError errorWithDomain...]);
                    }
                });
            });
        }
    }
}
0
albert102
-21 / 1 / 0
Регистрация: 30.10.2013
Сообщений: 53
19.05.2014, 08:52  [ТС] #5
спасибо за совет!
Identifier добавлять, чтобы потом обратиться к этой аннотации, например, из класса placeMark?

Добавлено через 2 минуты
placemark выглядит так у меня:

placeMark.h

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
 
@interface PlaceMark : NSObject <MKAnnotation> {
    CLLocationCoordinate2D coordinate;
    NSString *markTitle, *markSubTitle;
}
 
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, retain) NSString *markTitle, *markSubTitle;
 
 
-(id)initWithCoordinate:(CLLocationCoordinate2D)theCoordinate
           andMarkTitle:(NSString *)theMarkTitle
        andMarkSubTitle:(NSString *)theMarkSubTitle;
 
@end
placeMark.m

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#import "PlaceMark.h"
 
@implementation PlaceMark
@synthesize coordinate;
@synthesize markTitle, markSubTitle;
 
-(id)initWithCoordinate:(CLLocationCoordinate2D)theCoordinate andMarkTitle:(NSString *)theMarkTitle andMarkSubTitle:(NSString *)theMarkSubTitle{
    coordinate = theCoordinate;
    markTitle = theMarkTitle;
    markSubTitle = theMarkSubTitle;
    return self;
}
 
 
- (NSString *)title {
    return markTitle;
}
 
- (NSString *)subtitle {
    return markSubTitle;
}
 
 
@end
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
19.05.2014, 09:19 #6
Цитата Сообщение от albert102 Посмотреть сообщение
Identifier добавлять, чтобы потом обратиться к этой аннотации, например, из класса placeMark?
Нет, для того, чтобы не пересоздавать каждый раз кучу отображений для аннотаций. Поэтому вероятно и лагает.
Цитата Сообщение от albert102 Посмотреть сообщение
placemark выглядит так у меня:
Ну вот и добавьте загрузку картинки в этот же класс. Чтобы он отвечал за все данные, чтобы загрузка картинок не была "где-то" в контроллере.
0
albert102
-21 / 1 / 0
Регистрация: 30.10.2013
Сообщений: 53
19.05.2014, 09:21  [ТС] #7
но я так понимаю Identifier нужен рандомный для каждой аннотации ведь?
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
19.05.2014, 09:40 #8
Нет, смысла в рандомном идентификаторе не очень много, читайте документацию.
0
albert102
-21 / 1 / 0
Регистрация: 30.10.2013
Сообщений: 53
19.05.2014, 09:48  [ТС] #9
почитал документацию, понял принцип.
понял что не совсем верно в коде сделал.

однако я понять не могу следующее:
допустим я загрузил массив из 10 аватарок, если для каждой аватарки будет использован один Identifier - в чем смысл тогда?
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
19.05.2014, 10:09 #10
Цитата Сообщение от albert102 Посмотреть сообщение
допустим я загрузил массив из 10 аватарок, если для каждой аватарки будет использован один Identifier - в чем смысл тогда?
В том, что 10 штук создастся отображений, вы потом карту помотаете туда-сюда, и "новые" отображения не буду создаваться, а возьмутся те, что не на экране, а просто созданы были. Переиспользуемость.
0
albert102
-21 / 1 / 0
Регистрация: 30.10.2013
Сообщений: 53
20.05.2014, 07:32  [ТС] #11
все, окончательно понял.
я не сразу понял, что при скроллинге, карта их снова перегружает.

огромное спасибо!

Добавлено через 21 час 18 минут
скажите, пожалуйста, откуда такая инфа, что карта перерисовывает\перезагружает все аннотации при малейшем скроллинге?

натыкал nslog в нескольких местах внутри viewForAnnotation - в итоге выяснил, что срабатывает только после addAnnotation
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
20.05.2014, 10:39 #12
Цитата Сообщение от albert102 Посмотреть сообщение
при малейшем скроллинге?
А вы где увидели что я такое писал?
0
noname_club
103 / 94 / 10
Регистрация: 01.05.2013
Сообщений: 598
20.05.2014, 11:00 #13
все просто, аннотации на карте работают как ячейки в UITableView

Если вы знаете как работают ячейки, как они "пересоздаются" и "кешируются" то не сложно понять как точно такойже механизм работает на карте.
0
albert102
-21 / 1 / 0
Регистрация: 30.10.2013
Сообщений: 53
20.05.2014, 13:18  [ТС] #14
что то я совсем запутался.

доработал так, все авы загоняю в кэш после первой скачки, чтобы постоянно одну и туже аву не скачивать.
и применяю к аннотации. - дало +, теперь авы появляются быстро при втором и последующих отображениях.

далее, к сожалению, один identifier использовать не получилось, так как потом при клике на аву, у меня задумано модальное окно с авой большего размера, так вот в этом окне появляется другая ава. в итоге привязал identifier к id каждого юзера, чтобы не запуталось - работает как надо. но при этом подтормаживание как было так и осталось.

тем более, что reused как я понимаю используется при втором и последующих отображениях - но у меня подтормаживание появляется сразу при первом отображении аннотаций.

сегодня подрузку аватарок выведу в другую функцию и посмотрю как будет.

что касается tableview, но ведь там чуть подругому, таблички перезагружаются когда вначале уходят за видимую область экрана и потом возвращаются? до этого писал приложение, которое tableview использует и выводит 50 аватарок - никаких торможений небыло. понравилась автоматическая подгрузка.

Добавлено через 55 минут
от размера файла авы кстати торможение на зависит,
попробовал сейчас вместо 20 аватарок по 12 кб, добавить 1 аннотацию с картинкой 1.5 мб. - все летает.

собственно подтормаживание возникает когда масштаб карты очень маленький, и все 20 авок видны на экране.
когда масштаб до улиц увеличить, когда половина аватарок за пределом экрана находится - подтормаживания нет.
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
20.05.2014, 14:23 #15

Не по теме:

albert102, я бы вам сказал открыть инструметы и профайлингом на узкие места использования CPU посмотреть, но врят-ли это поможет, если вы после 2х дней колупания до сих пор не разобрались что такое reuseIdentifier и для чего он нужен.


Но все равно. Вы написали много слов да все не по делу.
Откройте профайлер и смотрите использование CPU/памяти в разные моменты использования приложения.

Цитата Сообщение от albert102 Посмотреть сообщение
понравилась автоматическая подгрузка.
Что это такое "автоматическая подгрузка"?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.05.2014, 14:23
Привет! Вот еще темы с ответами:

Видео подтормаживает при просмотре через браузеры [LPOG] - Удаление вирусов
А если просто с харда смотрим фильм, что все нормально. Может что-то в браузерах заразное поселилось.

Подтормаживает видео в браузере, при запуске windows появляется на несколько сек cmd. exe - Удаление вирусов
Пожалуйста, посмотрите вот логи

Вылетает при прокрутке - Программирование Android
Доброе утро. Тут небольшая проблема возникла. У меня в ListView формируется список категорий, их порядка 1000 а может и больше,...

Действие при прокрутке вниз - Windows Phone
помогите пожалуйста мне нужно чтоб при прокрутке списка вверх сверху появлялся TextBox а при прокрутке вниз то убирался помогите как это...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
20.05.2014, 14:23
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru