2009-10-06 6 views
1

Dans mon application iPhone, les vues se chargent souvent lentement lors de la transition, comme si un utilisateur cliquait sur un bouton du contrôleur de barre d'onglets. Cela arrive plus si le téléphone manque de mémoire. Cela n'arrive pas vraiment sur les téléphones 3GS, mais c'est un gros problème sur les téléphones 3G.Les vues se chargent lentement lors de la commutation entre les vues sur les iPhones 3G - comment changer de style?

Je suspecte que je ne suis pas les meilleures pratiques pour créer UIViewControllers. Je pense que je pourrais faire trop dans les fonctions d'init, n'utilisant pas la fonction viewDidLoad, ou quelque chose. Cela semble affecter toutes mes opinions, donc je pense que c'est un problème avec mon style en général, pas un extrait particulier. Est-ce que quelqu'un peut me dire ce que je peux faire mal? Voici un exemple de code provenant d'une sous-classe UIViewController:

EDIT: En réponse à la question: "Où est-ce que cela s'appelle?"

Cette fonction est appelée dans ce cas, lorsque l'utilisateur clique sur un marqueur sur la carte:

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

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

} 

FIN EDIT

-(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); 

} 
+0

Question: Où self.view est-il réglé? Dans un .xib, ou dans une autre méthode? De plus, qu'appelle initBookmarkView? – cduhn

Répondre

1

La lenteur que vous voyez peut probablement attribué au fait que la construction d'objets et la lecture de données à partir du flash sont des processus coûteux. Recherchez des opportunités de réutiliser des objets existants plutôt que de les construire plusieurs fois, et envisagez de différer des opérations particulièrement coûteuses jusqu'à ce que la vue s'affiche.

Dans ce cas, je voudrais commencer par un changement de couple:

  1. Faire savedBookmark une variable membre de sorte que vous pouvez construire une fois et le réutiliser. Remplacez votre méthode initBookmarkView: par une méthode setBookmarkView: que vous pouvez appeler après avoir construit cette variable membre pour reconfigurer vos libellés pour le signet spécifique affiché. Prenez le code de création de la sous-vue dans initView et placez-le dans loadView. C'est l'endroit le plus approprié pour construire votre propre hiérarchie de vue par programmation. UIViewController implémente un chargement paresseux sur sa propriété view pour reporter la construction le plus longtemps possible. La propriété view est nulle jusqu'à la première demande. À ce stade, UIViewController appelle loadView pour définir la propriété. L'implémentation par défaut charge la vue à partir d'un fichier nib si un fichier est défini. Sinon, il construit simplement un UIView vide et en fait la vue principale. Notez que vous devrez construire la vue du conteneur et définir vous-même la propriété d'affichage.

Dans d'autres applications que vous pouvez obtenir une certaine amélioration en déplaçant un code d'initialisation dans viewDidLoad :, appelée une fois la propriété de vue est chargé, que ce soit par programme ou d'une pointe. Si vous avez déjà une opération particulièrement lente comme le chargement d'images à partir d'une URL distante, vous pouvez commencer à charger les données de manière asynchrone dans viewDidLoad :, puis mettre à jour vos sous-vues une fois le chargement des données terminé. Dans certains cas, vous pouvez également reporter un code jusqu'à viewDidAppear :. Sachez que cette méthode est appelée chaque fois que la vue apparaît, contrairement à loadView et viewDidLoad :, qui ne sont appelés qu'une seule fois.

Questions connexes