0

UINavigationControllerとUITableviewをサブクラス化していますが、適切なメソッドとリリース呼び出しをすべて実装しましたが、何らかの理由でビューのメモリリークが発生しています。サブクラスの代わりにネイティブクラスを使用すると、リークすることなくすべてが正常に機能します。

編集:

これが私のスーパークラスヘッダーです:

//
//  MBAbstractViewController.h
//  GabbaiHD
//
//  Created by Moshe Berman on 11/24/10.
//  Copyright 2010 MosheBerman.com. All rights reserved.
//

#import <UIKit/UIKit.h>


@interface MBAbstractViewController : UIViewController {
    IBOutlet UIImageView *backgroundImageView;
    NSString *announcementText;
}

@property (nonatomic, retain) NSString *type;
@property (nonatomic, retain) NSDictionary *options;
@property (nonatomic, retain) NSString *announcementText;

-(void) setAnnouncementText:(NSString *)text;

@end

スーパークラスの実装:

//
//  MBAbstractViewController.m
//  GabbaiHD
//
//  Created by Moshe Berman on 11/24/10.
//  Copyright 2010 MosheBerman.com. All rights reserved.
//

#import "MBAbstractViewController.h"


@implementation MBAbstractViewController

@synthesize type, options, announcementText;

 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization.
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    UIColor *clearColor = [[UIColor alloc] colorWithAlphaComponent:0.0];
    [self.view setBackgroundColor: clearColor];
    [clearColor release];
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||  interfaceOrientation == UIInterfaceOrientationLandscapeRight){
        return YES;
    }else{
        return NO;
    }
}

- (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 {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;

}


- (void)dealloc {
    [announcementText release];
    [options release];
    [type release];
    [super dealloc];
}


@end

これが私のサブクラスヘッダーです:

//
//  MBAnnouncementViewController.h
//  GabbaiHD
//
//  Created by Moshe Berman on 11/24/10.
//  Copyright 2010 MosheBerman.com. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "MBAbstractViewController.h"

@interface MBAnnouncementViewController : MBAbstractViewController {
    IBOutlet UILabel *announcement;
}

- (void) setAnnouncementText:(NSString *)text withSize:(CGFloat)size;

@end

およびサブクラスの実装:

        //
//  MBAnnouncementViewController.m
//  GabbaiHD
//
//  Created by Moshe Berman on 11/24/10.
//  Copyright 2010 MosheBerman.com. All rights reserved.
//

#import "MBAnnouncementViewController.h"
#import "Constants.h"[

@implementation MBAnnouncementViewController

 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization.
    }
    return self;
}
*/


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];

    [announcement setText:announcementText]; 

    UIImage *slideImage = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[[NSString stringWithFormat:@"%@_slide", kTheme]description] ofType:@"png"]];  
    [backgroundImageView setImage:slideImage];
    [slideImage release];   


}



- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Overriden to allow any orientation.
    return YES;
}


- (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) setAnnouncementText:(NSString *)text withSize:(CGFloat)size{
    UIFont *font = [[UIFont alloc] fontWithSize:size];
    [announcement setFont:font];
    [font release];
    [announcement setText:text];

}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [announcementText release];
    [super dealloc];
}


@end

サブクラスでメモリリークを引き起こしている可能性があるのは何ですか?私は何かが足りないのですか?(ここにはもっと関連性のあるコードがあります。)

4

4 に答える 4

2

サブクラスに、スーパークラスに表示されていないように見える「アナウンス」変数があることに気付きました。

あなたのスーパークラスには次の変数があると思います:

type
options
announcementText

サブクラスには追加の変数がありますが、次のようになります。

announcement

サブクラスのdeallocで、リリースannouncementText(スーパークラスでもリリースされます)ではなくannouncement、リリースします。これがリークの原因である可能性があります。

于 2010-11-29T22:10:21.153 に答える
1

UIColorこのように割り当てることはできません。

[[UIColor alloc] colorWithAlphaComponent:0.0];

インスタンスを初期化せずに割り当てた後、ファクトリメソッドを呼び出し、割り当てたインスタンスへの参照を失いました。

を呼び出す前に、初期化子の1つを呼び出すことをお勧めしますcolorWithAlphaComponent:。そうしないとどうなるかわかりません。なぜだけではないの[UIColor clearColor];ですか?

あなたも同じ過ちを犯していUIFontます:

UIFont *font = [[UIFont alloc] fontWithSize:size];

これは絶対にしないでください。チェーンする唯一のメソッドは+alloc初期化子である必要があります(常に割り当てられたものを返します)。あなたはここで漏れていて、私が敢えて言ういくつかの奇妙な意図しない振る舞いも受けています。

また、David Liuが言うように、あなたは過剰放出announcementTextと過少放出のように見えますannouncement。これは、あなたがどれだけ幸運に恵まれたかによって、クラッシュとリークの両方を引き起こします。

編集| ヘッダーファイルを表示する更新に基づいて、さらに問題があります(特にリークとは関係ありません)。

@property (nonatomic, retain) NSString *announcementText;

あなたは決して保持するべきではありませんNSString*; 代わりにあなたはcopyそれをすべきです。

@property (nonatomic, copy) NSString *announcementText;

これは、NSString*実際には変更可能な文字列であり、後で変更される可能性があるためです。retainただし、これが特に必要な場合は使用できます。

-setAnnouncementText:また、を持っているときに明示的に宣言する必要はありません@property announcementText

あなたのサブクラスでsetAnnouncementText:withSize:は、実際にはannouncementTextivarには何もしませんが、これは混乱を招くと思います。ivarをリリースして、(リークしている)誤って使用されている問題announcementを修正する必要があります。UIColorUIFont

于 2010-11-29T22:35:51.877 に答える
0

UIViewControllerのドキュメントによると

...ビューコントローラにアウトレット(IBOutletキーワードを含むプロパティまたはraw変数)が含まれている場合は、viewDidUnloadメソッドを使用して、これらのアウトレットまたは不要になったその他のビュー関連データの所有権を放棄する必要があります。

それはIBOutletなので、リリースannouncementしてみてください。InterfaceBuilderはそれを保持します。viewDidUnload

- (void)viewDidUnload {
    [super viewDidUnload];
    [announcement release];
    announcement = nil;
}
于 2010-11-29T21:40:39.723 に答える
0

2番目のクラスで「発表」は何を表していますか?それはIBOutletですか(私はそれの合成を見ていません)?プロパティまたはIBOutletの場合は、必ずdeallocでリリースする必要があります。

于 2010-11-29T21:55:53.790 に答える