Mam aplikację na iPhone'a, która ładuje kolejne widoki w strukturze opartej na tym explained in this link (w zasadzie główny ViewController
, który ładuje/usuwa dodatkowe widoki za pomocą metody displayView
). W mojej aplikacji używam NIBs (przykładowy link używa zakodowanych widoków), więc każdy z moich ViewControllers
ma dołączoną końcówkę.Aplikacja dla iPhone'a z wieloma widokami/podskokami: pamięć nie jest wycofywana.
debugowanie instrumentami pokazuje ma wycieków ale gdybym wejść/opuścić sekcję (ViewController z View.xib), Stalówka pozostaje w pamięci tak po kilka w/out pamięć zaczyna gromadzić.
Wiem, że stalówka nie jest rozładowywana, ponieważ jedna jest prawie programowana (brak elementów w IB), a druga ma obrazy i przyciski utworzone w IB. Duży ładowany jest pierwszy, a mały ładowany dalej. Spodziewałbyś się zmniejszenia alokacji w Instrumentach.
Jak mogę temu zapobiec?
Moja struktura wygląda następująco, z kilkoma uwagami poniżej:
`MyAppDelegate.h`
#import <UIKit/UIKit.h>
@class RootViewController;
@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *viewController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet RootViewController *viewController;
-(void) displayView:(int)intNewView;
@end
`MyAppDelegate.m`
#import "MyAppDelegate.h"
#import "RootViewController.h"
@implementation MyAppDelegate
@synthesize window;
@synthesize viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
}
-(void) displayView:(int)intNewView {
[viewController displayView:intNewView];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end
Sterownik ten obsługuje obciążenie subview/Usuwa:
`RootViewController.h`
#import <UIKit/UIKit.h>
@interface RootViewController : UIViewController {
}
- (void) displayView:(int)intNewView;
@end
`RootViewController.m`
#import "RootViewController.h"
#import "ViewController.h"
@implementation RootViewController
UIViewController *currentView;
- (void) displayView:(int)intNewView {
NSLog(@"%i", intNewView);
[currentView.view removeFromSuperview];
[currentView release];
switch (intNewView) {
case 1:
currentView = [[ViewController alloc] initWithNibName:@"View" bundle:nil];
break;
}
[self.view addSubview:currentView.view];
}
- (void)viewDidLoad {
currentView = [[ViewController alloc]
initWithNibName:@"View" bundle:nil];
[self.view addSubview:currentView.view];
[super viewDidLoad];
}
- (void)dealloc {
[currentView release];
[super dealloc];
}
@end
Nie byłoby tyle case
jako "Detail" ViewControllers
I mieć (teraz mam 3 case
, ale ten wzrośnie do 10 lub więcej). Celem tej struktury jest łatwe przejście z jednej "sekcji" aplikacji do drugiej (kontroler NavBar lub kontroler TabBar nie odpowiada moim potrzebom).
`ViewController.h`
// Generic View Controller Example
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController {
UIImageView *_image1;
UIImageView *_image2;
NSTimer *_theTimer;
}
@property (nonatomic, retain) IBOutlet UIImageView *image1;
@property (nonatomic, retain) IBOutlet UIImageView *image2;
@property (nonatomic, retain) NSTimer *theTimer;
@end
`ViewController.m`
#import "ViewController.h"
#import "MyAppDelegate.h"
@synthesize image1 = _image1, image2 = _image2, theTimer = _theTimer;
- (void)loadMenu {
[self.theTimer invalidate];
self.theTimer = nil;
MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate displayView:2];
}
-(void)setView:(UIView*)aView {
if (!aView){
self.image1 = nil;
self.image2 = nil;
}
[super setView:aView];
}
- (void)viewDidLoad {
//some code
[super viewDidLoad];
}
- (void)viewDidUnload {
self.image1 = nil;
self.image2 = nil;
}
- (void)dealloc {
NSLog(@"dealloc called");
[self.theTimer invalidate];
[self.theTimer release];
[self.image1 release];
[self.image2 release];
[super dealloc];
}
Zawiadomienie NSLog
w dealloc
. To jest wywoływane (widzę to w konsoli), ale pamięć potrzebna na stalówkę nie jest zwalniana (Instrumenty pokazują zwiększenie alokacji pamięci podczas opuszczania sekcji, ponieważ ładowany jest nowy stalówka).
Każda pomoc zostanie bardzo doceniona. Wypróbowałem milion różnych rzeczy i nie mogę zmusić stalówki do rozładowania.
Możesz pobrać moją wersję frameworka z poprawką tutaj: http://www.mauriciogiraldo.com/blog/2009/10/09/multiples-views-no-jerarquicas-en-iphone/ Przewiń w dół, aby zobaczyć angielski tłumaczenie. – mga