gpt4 book ai didi

具有多个 View / subview 的iPhone应用程序: memory is not being deallocated

转载 作者:行者123 更新时间:2023-12-03 18:57:02 25 4
gpt4 key购买 nike

我有一个 iPhone 应用程序,它在基于 explained in this link 的框架中加载连续 View 。 (基本上是一个主ViewController,它使用displayView方法加载/删除其他 View )。在我的应用程序中我使用NIB(示例链接使用编码 View ),因此我的每个ViewControllers都有其随附的nib。

仪器中的调试显示没有泄漏,但如果我进入/离开一个部分(ViewController 及其 View.xib), Nib 仍保留在内存中,因此在几次输入/输出后内存开始累积。

我知道 Nib 没有被卸载,因为一个 Nib 几乎是通过编程创建的(IB 中没有任何内容),而另一个 Nib 确实在 IB 中创建了图像和按钮。首先加载大的,然后加载小的。您预计工具的分配会减少。

如何防止这种情况发生?

我的结构如下,下面有一些评论:

`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

该 Controller 处理 subview 加载/删除:

`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

case 的数量与我拥有的“detail”ViewControllers 一样多(现在我有 3 个 case,但这将增加到 10 个)或者更多)。这种结构的目的是轻松地从应用程序的一个“部分”移动到另一个“部分”(NavBar Controller 或 TabBar Controller 不适合我的特定需求)。

`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];
}

注意dealloc中的NSLog。这正在被调用(我可以在控制台中看到它),但 Nib 所需的内存未释放(仪器显示离开部分时内存分配增加,因为加载了新 Nib )。

任何帮助将不胜感激。我已经尝试了一百万种不同的东西,但我无法卸载 Nib 。

最佳答案

经过一百万次不同的尝试,我终于遇到了 this forum .

它指出:

Apparently images assigned in IB are loaded into image views using imageNamed. imageNamed caches the images in a way that makes them unloadable. You could load the images in viewDidLoad with initWithContentsOfFile and then assign them to the views.

我在其他地方读过imageNamed is the devil所以我不想让我的图像以这种方式加载。

(顺便说一句,这是我正在使用的 iPhone OS 3.1)

我最终的结果是在 IB 中完整保留 UIImageView ,但 .image 值为空。修改后的代码如下:

- (void)viewDidLoad {
NSString *path = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], @"myImageThatBeforeWasAValueinIB.jpg"];
UIImage *image = [UIImage imageWithContentsOfFile:path];
outlet.image = image;
// do the rest of my stuff as it was
[super viewDidLoad];
}

- (void)dealloc {
outlet.image = nil;
[outlet release], outlet = nil;
[super dealloc];
}

现在一切都很顺利!当我卸载 Nib 以及收到内存警告时,内存就会恢复。

所以,如果你有用于 UIImageViewIBOutlets 并且内存是一个问题(我猜它总是如此),你可以在 IB 中设计你想要的一切,当是时候将它们连接到 socket 、删除 IB 中的图像引用并从代码创建它了。 IB 非常适合布置您的应用程序。必须通过代码完成所有这些事情会很糟糕,但我还发现 this nice utility that converts nibs to objective c代码虽然我还没有测试过。

关于具有多个 View / subview 的iPhone应用程序: memory is not being deallocated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1482934/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com