0

編集:わかりましたので、元の問題を解決する方法を見つけましたが、これが最善の方法であるかどうかはわかりません。

私の新しい質問は、ヘッダーに次のプロパティ宣言を持つ UITableViewCell のサブクラスがあるとします。

@property (nonatomic, retain) IBOutlet UILabel *levelLabel;

これは IB で接続されます。これを dealloc で解放せず、まったく解放しなくても大丈夫ですか? これは、exc_bad_access エラーを発生させずに動作させることができる唯一の方法です。以前は、tableviewcell が画面から消えたときに dealloc が呼び出されましたが、それでも必要でした。どこでリリースするのですか?

元のタイトル: UITableView と exc_bad_access でメモリ リークが発生しました。私はカスタム UITableViewCells をオンラインで作成するこのチュートリアルに従っていました。私は1つを作成し、チュートリアルが教えてくれたようにすべてを行いました. 私の UITableViewCell サブクラスには 3 つの UILabels と 3 つの UIButton が含まれており、それらはすべてプロパティとして定義され、IB で接続されています。ボタンがいつ押されたかを知り、テキストを変更できるようにする必要があるため、それらをクラスで使用できるようにする必要があります。アプリを実行すると、スクロールが開始され、数秒後にクラッシュし、メインに exc_bad_access が表示されます (コンソールに出力はありません)。しかし、NSZombieEnabled を使用してインストゥルメントでアプリを実行すると、アプリはまったくクラッシュせず、問題なく実行されます。ただし、楽器は割り当てを表示するため、特にスクロールすると、割り当てが非常に速く増加することがわかります。

これが PointCoordinatesCell.h (私のカスタム セル) です。

#import <UIKit/UIKit.h>

@interface PointCoordinatesCell : UITableViewCell


@property (nonatomic, retain) IBOutlet UILabel *levelLabelLabel;
@property (nonatomic, retain) IBOutlet UILabel *levelLabel;
@property (nonatomic, retain) IBOutlet UILabel *levelDescriptionLabel;
@property (nonatomic, retain) IBOutlet UIButton *beginningButton;
@property (nonatomic, retain) IBOutlet UIButton *developingButton;
@property (nonatomic, retain) IBOutlet UIButton *secureButton;

@end

PointCoordinatesCell.m:

#import "PointCoordinatesCell.h"

@implementation PointCoordinatesCell
@synthesize levelLabel, levelLabelLabel, levelDescriptionLabel, beginningButton, developingButton, secureButton;

- (void)dealloc{
    [super dealloc];
    [levelLabel release];
    [levelLabelLabel release];
    [levelDescriptionLabel release];
    [beginningButton release];
    [developingButton release];
    [secureButton release];
}

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end

RootViewController.h には、クラス宣言と標準インポート以外は何も含まれていません。変数またはメソッドが定義されていません。UITableViewController をサブクラス化します。

RootViewController.m:

#import "RootViewController.h"
#import "StatesAppDelegate.h"
#import "PointCoordinatesCell.h"

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];


    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}

#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 50;
}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    return 293;
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"PointCoordinatesCell";

    PointCoordinatesCell *cell = (PointCoordinatesCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {

        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"PointCoordinatesCell" owner:self options:nil];

        for (id currentObject in topLevelObjects){
            if ([currentObject isKindOfClass:[UITableViewCell class]]){
                cell =  (PointCoordinatesCell *) currentObject;
                break;
            }
        }
    }

    //cell.capitalLabel.text = [capitals objectAtIndex:indexPath.row];
    //cell.stateLabel.text = [states objectAtIndex:indexPath.row];

    return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.
    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
    // [self.navigationController pushViewController:anotherViewController];
    // [anotherViewController release];
}



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


@end
4

2 に答える 2

0

メソッドで複雑なキャストを行っているようですcellForRowAtIndexPath。これは必要ないと思います。UITableViewCellクラスのオブジェクトをチェックしてからカスタムセルにキャストすることは、私には論理的ではないようです。nib のセルは、既にカスタム セルになっているはずです。

Apple のサンプルでは、​​セルのロードはより簡単です。カスタム セルをIBOutletView Controller の にリンクしてから、次の操作を行います。

CustomCell *cell = (CustomCell *) [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
    cell = customTableViewCell;
    self.customTableViewCell = nil;
    // etc.
}
于 2011-08-28T19:23:04.787 に答える
0

いいえ、ラベルをリリースしないとダメです。'retain'-specifier を使用してプロパティを宣言しました。つまり、少なくとも dealloc で解放する必要があります (安全な方法は次のとおりですself. levelLabel = nil;)。

お気づきのように、オブジェクトを解放しないと、スクロール中にメモリ消費量が増加します (メモリ リーク!)。

私たちがあなたを助けることができるように、あなたは exc_bad_access エラーが発生した場所を伝える必要があります...

于 2011-08-28T19:21:30.957 に答える