При переключении между представлениями на 3G-айфонах представления загружаются медленно - как изменить мой стиль? - PullRequest
1 голос
/ 07 октября 2009

В моем приложении для iPhone представления при загрузке часто загружаются медленно, например, если пользователь нажимает кнопку на контроллере панели вкладок. Это происходит чаще, если у телефона мало памяти. Это действительно не подходит для телефонов 3GS, но это большая проблема для телефонов 3G.

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

Может кто-нибудь сказать мне, что я могу делать неправильно? Вот пример кода из подкласса UIViewController:

РЕДАКТИРОВАТЬ: В ответ на вопрос: "где это называется?"

Эта функция вызывается в этом случае, когда пользователь щелкает маркер на карте:

if(marker.label.tag == SavedBookmarkTag) {

  SavedDetailScreen *savedBookmark = [[[SavedDetailScreen alloc] initBookmarkView:
    [(NSDictionary *)marker.data objectForKey:@"bookmark"]]autorelease];
    [savedBookmark showMap];
    [self.navBar pushViewControllerWithBackBar:savedBookmark];
    return;

}

КОНЕЦ РЕДАКТИРОВАНИЯ

-(id)initBookmarkView: (Bookmark *)bm {

    self = [self initView];
    self.bookmark = bm;

    primaryLabel.text = [bm title];
    secondaryLabel.text = [self getLineWithLat:[bm lat] AndLon:[bm lon] AndDate:[bm timeCreated]];
    return self;

}


- (id)initView {

  self = [super init];
  self.isWaypoint = NO;

  UIImageView *bg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"238-beveled-background.png"]];

  bg.frame = CGRectMake(0, 0, 320, 376);
  [self.view addSubview:bg];
  bg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"small-label.png"]];
  [self.view addSubview:bg];
  [bg release];

  self.primaryLabel = [[UILabel alloc]init];
  primaryLabel.font = TITLE_FONT;
  primaryLabel.backgroundColor = [UIColor clearColor];
  primaryLabel.textColor = LIGHT_BLUE;

  self.secondaryLabel = [[UILabel alloc]init];
  secondaryLabel.font = TEXT_FONT;
  secondaryLabel.backgroundColor = [UIColor clearColor];
  secondaryLabel.textColor = LIGHT_BLUE;
  secondaryLabel.lineBreakMode = UILineBreakModeClip;

  self.thirdLabel = [[UILabel alloc]init];
  thirdLabel.font = TEXT_FONT;
  thirdLabel.backgroundColor = [UIColor clearColor];
  thirdLabel.textColor = LIGHT_BLUE;
  thirdLabel.lineBreakMode = UILineBreakModeCharacterWrap;

  [self.view addSubview:primaryLabel];
  [self.view addSubview:secondaryLabel];
  [self.view addSubview:thirdLabel];    

  self.loadingBackground = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"stats-box.png"]];
  loadingBackground.frame = CGRectMake(0, 115, loadingBackground.frame.size.width, loadingBackground.frame.size.height);
  [self.view addSubview:loadingBackground];
  [self.view sendSubviewToBack:loadingBackground];

  AnimatedGif *animatedGif = [[[AnimatedGif alloc] init] autorelease];
  NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"35" ofType:@"gif"]]; 
  [animatedGif decodeGIF: data];

  UIImageView *loadingImage = [animatedGif getAnimation];
  loadingImage.frame = CGRectMake(150,150,loadingImage.frame.size.width,loadingImage.frame.size.height);

  [loadingImage startAnimating];    
  [loadingBackground addSubview:loadingImage];
  [loadingImage release];

  [self layoutSubviews];

  return self;

}   


- (void) layoutSubviews {

    self.view.frame = CGRectMake(0,0,320,372);
    primaryLabel.frame = CGRectMake(30, 30, 260, 18);
    secondaryLabel.frame = CGRectMake(30 ,52, 260, 16);
    thirdLabel.frame = CGRectMake(30, 72, 260, 16);

}

1 Ответ

1 голос
/ 07 октября 2009

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

В этом случае я бы начал с пары изменений:

  1. Сделайте saveBookmark переменной-членом, чтобы вы могли создать ее один раз и использовать повторно. Замените ваш initBookmarkView: метод на setBookmarkView: метод, который вы можете вызвать после создания этой переменной-члена, чтобы перенастроить ваши метки для конкретной отображаемой закладки.

  2. Извлеките код создания подпредставления из initView и поместите его в loadView. Это наиболее подходящее место для программного построения собственной иерархии представлений. UIViewController реализует отложенную загрузку своего свойства view, чтобы отложить конструкцию как можно дольше. Свойство view равно nil до первого запроса. В этот момент UIViewController вызывает loadView для установки свойства. Реализация по умолчанию загружает представление из файла пера, если он определен. В противном случае он просто создает пустой UIView и делает его основным видом. Обратите внимание, что вам придется создать контейнерное представление и установить свойство представления самостоятельно.

В других приложениях вы можете получить некоторое улучшение, переместив некоторый код инициализации в viewDidLoad:, который вызывается после загрузки свойства представления, программно или из кончика. Если у вас когда-либо есть особенно медленная операция, такая как загрузка изображений с удаленного URL-адреса, вы можете начать асинхронную загрузку данных в viewDidLoad:, а затем обновить свои подпредставления, как только данные завершат загрузку. В некоторых случаях вы также можете отложить некоторый код до viewDidAppear :. Просто имейте в виду, что этот метод вызывается каждый раз, когда появляется представление, в отличие от loadView и viewDidLoad :, которые вызываются только один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...