9

レイアウトに.xibファイルを使用し、追加のセットアップにバッキングクラスを使用するカスタム作成のUIViewがいくつかあります。alloc / initを使用してこれらのクラスを作成し、カスタムinitメソッドでloadNibNamedを呼び出しましたが、そうするとメモリリークが発生していました。誰かがalloc部分が実際にリークしている自己オブジェクトを作成したことを指摘したので、私はinitメソッドをこれに調整しました:

- (id)init 
{
    [self autorelease];
    self = [[[[NSBundle mainBundle] loadNibNamed:@"AssignmentView" owner:nil options:nil] lastObject] retain];
    [self setupBranding];

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected:)];
    [self addGestureRecognizer:tapRecognizer];
    [tapRecognizer release];

    return self;
}

ただし、分析コードを実行すると、「[(superまたはself)init...]'の結果に設定されていないときに'self'を返す」という警告が表示されます。だから私の質問は、バッキングクラスでカスタムUIViewを実行するための正しい方法は何ですか?

尋ねられたので、私はこの上記のコードを次のように使用しました:

AssignmentView * assignmentView = [[AssignmentView alloc] init];
[self.view addSubview:assignmentView];
4

2 に答える 2

18

ビューを取得し、[NSBundle loadNibNamed:owner:options:],そのフレームをビューの境界に合わせて設定します。一般に、親ビューのサイズが変更されたときに、ペン先のビューもサイズ変更する必要があります。

これらを追加した UIView カテゴリがあります。

- (UIView *)viewFromNib
{
    Class class = [self class];
    NSString *nibName = NSStringFromClass(class);
    NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];
    UIView *view = [nibViews objectAtIndex:0];
    return view;
}


- (void)addSubviewFromNib
{
    UIView *view = [self viewFromNib];
    view.frame = self.bounds;
    [self addSubview:view];
}

次に、 -initWithFrame: メソッドは次のようになります。

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubviewFromNib];
    }
    return self;
}

これを機能させるには、nib がクラスと同じ名前であることを確認してください。

于 2012-08-17T00:20:56.847 に答える
7

便利なコンストラクター スタイルの使用を検討しますか?

+ (AssignmentView *)assignmentView
{
    AssignmentView *result = [[[NSBundle mainBundle] loadNibNamed:@"AssignmentView" owner:nil options:nil] lastObject];
    [result setupBranding];

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected:)];
    [result addGestureRecognizer:tapRecognizer];
    [tapRecognizer release];

    return result;
}

ビューを構築するときに必要と思われる柔軟性を提供しますが、メモリ リークや警告は発生しません。

于 2012-08-17T00:22:40.120 に答える