Pergunta

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 estou lidando envolve 2 instâncias da classe UIViewController. No arranque, a primeira instância é criada e seu ponto de vista é adicionado a outro "main" classe UIViewController 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 "principal" UIViewController 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 as pontas de aplicação. 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 torneira no botão "info" que existe na primeira instância UIViewController. Uma vez aproveitado, o "principal" UIViewController remove vista e substitui-lo com a pessoa certa para a tela de informações do UIViewController existente. A tela de informações tem um botão "voltar" para mudar os pontos de vista de volta. No entanto, uma vez que as folhas do usuário na tela 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 é vazamento 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 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?

Foi útil?

Solução

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 à base de NIB olhares controlador de vista, como 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

Outras dicas

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.

O segundo 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 singleton objetos ( com o código)

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

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

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 nível superior que são carregados a partir de um arquivo nib quando você não precisar mais deles.

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, transição para a informação vista. Se o usuário vai para trás, carregar a imagem da pasta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top