problemas de vazamento de memória UIViewController

votos
9

Semelhante ao problema de fuga de memória conhecida sobre a criação e destruição de uma instância do UIImagePickerController, eu estou encontrando problemas semelhantes em relação a instâncias da classe UIViewController. A maneira recomendada para usar o UIImagePickerController é criar a instância de uma vez e mantê-lo em torno de toda a vida útil da aplicação, eventhough este irá usar a memória que você pode precisar em outros lugares.

A situação que eu estou lidando com envolve 2 instâncias da classe UIViewController. No arranque, a primeira instância é criada e seu ponto de vista é adicionado a uma outra classe UIViewController main que faz parte do MainWindow.xib. Nesta primeira instância é um botão info que, quando bateu, muda para uma nova instância da classe UIViewController (se ele ainda não tiver sido criado). O UIViewController main gere este comutação com a animação flip habitual. A configuração básica pode ser visto no desenvolvimento do iPhone de início: Explorando o iPhone SDK livro de Dave Mark.

O problema que se coloca é que, uma vez o botão info é aproveitado pela primeira vez, a memória é alocada para a nova segunda instância UIViewController e não é liberado até que o aplicativo termina. Devido ao número de elementos nesta ver informações, ele usa aproximadamente 1 MB de memória, uma vez instanciado e seu ponto de vista é adicionado ao superview. Qualquer tentativa de destruir de forma consistente e recriar Esta instância resulta em um vazamento de memória, semelhante ao que existe se você tentar fazer a mesma coisa para as instâncias da classe UIImagePickerController. Eu suspeito que a causa raiz é a mesma entre as duas classes.

O cerne do meu problema envolve a necessidade de ter o máximo de memória liberada antes de permitir que o usuário tirar uma foto com a câmera. No entanto, uma vez que o usuário tenha tirado uma foto e não se veja a imagem resultante na primeira vez, eles estão autorizados a tocar no botão info que existe na primeira instância UIViewController. Uma vez aproveitado, o UIViewController main remove o ponto de vista do UIViewController existente e substitui-lo com o um para a tela de informações. A tela de informações tem um botão voltar para mudar os pontos de vista de volta. No entanto, uma vez que o usuário deixa a tela de informações e escolhe para tirar outra foto com a câmera, a memória alocada para a tela de informações ainda está na memória.

A classe UIImagePickerController usa temporariamente quase 15-18MB enquanto processa a imagem de 2 megapixels antes de liberar suas referências internas e os imagePickerController: didFinishPickingImage delegado é chamado. Eu estou correndo em alertas de pouca memória uma vez que a segunda instância UIViewController foi criado por meio do botão de informações e, em seguida, o usuário escolhe para tirar outra foto.

Memória tecnicamente não está vazando, se você tirar fotos mais e mais com ou sem tocar no botão de informação no meu caso, mas devido a outras questões relacionadas com processos em segundo plano no iPhone (Safari, etc.) que estão além de seu controle, você deve liberar -se tanta memória quanto possível ao trabalhar com coisas como a câmera.

Qualquer conselhos sobre como criar e destruir limpa instâncias da classe UIViewController tal que a memória não vaza?

Publicado 04/03/2009 em 00:08
fonte usuário
Em outras línguas...                            


4 respostas

votos
4

Você está carregando o segundo controlador de vista de um NIB? Se assim for, você vai querer verificar que você está liberando a memória associada corretamente.

Aqui está o que um típico controlador de vista baseado em NIB parece em meus projetos.

SomeViewController.h

@interface SomeViewController : UIViewController {
    UILabel *someLabel;
}

@property (nonatomic, retain) IBOutlet UILabel *someLabel;

@end

SomeViewController.m

@implementation SomeViewController

@synthesize someLabel;

- (void)dealloc {
    // Release our retained IBOutlets
    self.someLabel = nil;
    [super dealloc];
}

@end
Respondeu 09/03/2009 em 03:17
fonte usuário

votos
1

Você tem ciclos em sua cadeia de propriedade? Algo como:

@interface FirstViewController: UIViewController {
  SecondViewController *secondViewController;
}
@end

@interface SecondViewController: UIViewController {
  FirstViewController *firstViewController;
}
@end

Se você não quebrar explicitamente este ciclo quando você descartar esses controladores de vista, eles vão vazar.

Além disso, eu acredito que você é responsável por liberar todos os objetos de alto nível que são carregados a partir de um arquivo nib quando você não precisar mais deles.

Respondeu 05/03/2009 em 21:45
fonte usuário

votos
1

Uma forma de reduzir o uso de memória seria para redimensionar a imagem para o tamanho que você quer (a menos que naturalmente você quer uma imagem de 320x480). Isso ajudou muito no meu caso.

Será a segunda viewcontroller você está falando sobre mudança? Se não, então seria melhor para torná-lo um singleton e usar a mesma instância. Você pode a qualquer momento alterar os valores usados pelo viewcontroller. Este artigo explica como você pode criar objetos únicos (com o código)

Outro artigo aqui mostra o uso de uma única classe (embora diferente do seu caso de uso, ele irá esclarecer como usar singletons)

Gostaria de sugerir a criação de um objeto singleton para UIImagePickerController também.

Respondeu 05/03/2009 em 05:45
fonte usuário

votos
0

Talvez você poderia salvar a imagem antes de fazer a transição para a informação vista. Depois de salvar, libertar a imagem e, em seguida, a transição para a informação vista. Se o usuário vai para trás, carregar a imagem da pasta.

Respondeu 23/10/2009 em 21:28
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more