9

我有一些自定义创建的 UIViews,它们使用 .xib 文件进行布局,并使用支持类进行额外设置。我使用 alloc/init 创建这些类,并在我的自定义 init 方法中调用 loadNibNamed,但这样做会导致内存泄漏。有人指出 alloc 部分实际上创建了一个泄漏的 self 对象,所以我将我的 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;
}

但是,现在当我运行分析代码时,我收到此警告“返回'self',而它未设置为'[(super or self)init ...]'的结果”。所以我的问题是使用支持类进行自定义 UIViews 的正确方法是什么?

既然有人问我,我就使用了上面的代码,如下所示:

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

2 回答 2

18

从中获取视图 -[NSBundle loadNibNamed:owner:options:],然后设置其框架以匹配您的视图边界。通常,您还希望在调整其父视图大小时调整 nib 中的视图大小。

我们有一个带有这些添加的 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 回答