Управление памятью iPhone и плохой доступ - PullRequest
0 голосов
/ 05 сентября 2011

Очень многие мои вопросы о переполнении стека показывают мое разочарование по поводу управления памятью на iPhone SDK. Кажется, я устранил все основные утечки, но, похоже, есть проблема, которую трудно назвать утечкой. В соответствии с моим графиком распределения, когда я создаю Certian объекты, например, следующий перевернутый код вида, график не опускается туда, где он был до того, как объект был создан, но он немного снижается. Я предполагаю, что это происходит из-за объектов, выпущенных классом. Что мне кажется странным, так это то, что в следующий раз, когда будет выделено мое перевернутое представление, график не поднимется вверх, как это было бы в том, что я бы назвал утечкой. например, допустим, что мое приложение запускается с использованием, скажем, 1 МБ памяти, затем, когда отображается обратное представление, оно увеличивается до 3 МБ, после того как открывается обратное представление, оно уменьшается до 2 МБ, но при следующем представлении оно возвращается к 3 МБ вместо 4 МБ. , что с этим? Я неправильно читаю график? Я хочу, чтобы использование памяти вернулось к 1 МБ. У меня также возникает эта проблема, когда мое приложение переходит в фоновый режим, и я возиться с некоторыми другими приложениями, например, смотреть видео или просматривать в Интернете что-то, использующее память. Иногда, когда я возвращаюсь к своему приложению, я получаю:

Program received signal: “EXC_BAD_ACCESS”.warning: Unable to read symbols for     
/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.3 
(8J2)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib

У меня есть догадка, что это может быть связано.

Слушайте, это код для моего примера с обратной стороны

На моем главном экране контроллера

- (IBAction)showInfo
{
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:nil bundle:nil];

controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}

мой контроллер обзора с обратной стороны

#import "FlipsideViewController.h"
#import "MainViewController.h"

@implementation FlipsideViewController

- (void)viewDidLoad {
    self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];

    nav_bar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width+20,45)];
    // nav_bar retaincount 1
    [self.view addSubview:nav_bar];
    // nav_bar retaincount 2
    [nav_bar release];
    // nav_bar retaincount 1 - now controlled by self.view

    rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(done)];
    // rightButton retaincount 1

    item = [[UINavigationItem alloc] initWithTitle:@"Myapp Usage"];
    // item retaincount 1

    item.rightBarButtonItem = rightButton;
    // rightButton retaincount 2

    [rightButton release];
    // rightButton retaincount 1 - now controlled by item

    item.hidesBackButton = YES;
    [nav_bar pushNavigationItem:item animated:NO];
    // item retaincount 2

    [item release];
    // item retaincount 1 - now controlled by nav_bar

    web_view = [[UIWebView alloc]initWithFrame:CGRectMake(0,45,self.view.frame.size.width,self.view.frame.size.height - 45)];
    // web_view retaincount 1

    web_view.autoresizesSubviews = YES;
    web_view.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);


    [web_view loadRequest:[NSURLRequest requestWithURL:
                          [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Documentation" ofType:@"html"]isDirectory:NO]]];

    //[web_view loadRequest:requestObj];

    [self.view addSubview:web_view];
    // web_view retaincount 2

    [web_view release];
    // web_view retaincount 1 - now controlled by self.view

    [super viewDidLoad];
}

- (IBAction)done
{
    [self dismissModalViewControllerAnimated:YES];
    //[((MainViewController*)Controller) flipsideViewControllerDidFinish:self];
}

/*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations
 return (interfaceOrientation == UIInterfaceOrientationPortrait);
 }
 */

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
//  [nav_bar removeFromSuperview];
    printf("Unloaded\n");
}


- (void)dealloc {
    [web_view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
    printf("Flipside Dalloc\n");
    //[web_view loadHTMLString: @"" baseURL: nil];
    //[web_view removeFromSuperview];
    //[rightButton release];
    NSLog(@"%d",[nav_bar retainCount]);
    [super dealloc];
}

@end

и его заголовок:

@interface FlipsideViewController : UIViewController {
    UIWebView    *web_view;
    UINavigationBar  *nav_bar;
    UIBarButtonItem  *rightButton;
    UINavigationItem *item;
}

- (IBAction)done;

@end

1 Ответ

1 голос
/ 05 сентября 2011

Что выглядит немного странно, так это то, что вы выпустили nav_bar, а затем написали следующее ...

[nav_bar pushNavigationItem:item animated:NO];

Ваша логика сохранения количества верна, но логично думать, что когда вы отпустите nav_bar, эта переменная больше не будет ссылаться на объект.

Вы должны демонстративно отпустить его, но, наконец, когда вы закончите со всеми операциями. Подойдёт даже выпуск в dealloc.

Здесь ваше мнение о retainCount для nav_bar верно, но из этих двух ссылок на nav_bar, которыми вы владеете, только один другой принадлежит представлению, и представление освободит его. Так что освобождения вашей роли в функции dealloc будет достаточно.

Надеюсь, это полезно .....

...