使用.xib和支持类初始化UIView的正确方法

Rob*_*oth 9 initialization objective-c uiview ios

我有一些自定义创建的UIViews,它们使用.xib文件进行布局,并使用支持类进行额外设置.我使用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;
}
Run Code Online (Sandbox Code Playgroud)

但是,现在当我运行分析代码时,我得到这个警告"返回'自我',而它没有设置为'[(超级或自​​我)初始化...]"的结果.所以我的问题是使用支持类进行自定义UIViews的正确方法是什么?

既然有人问我上面的代码是这样的:

AssignmentView * assignmentView = [[AssignmentView alloc] init];
[self.view addSubview:assignmentView];
Run Code Online (Sandbox Code Playgroud)

Dav*_*ton 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];
}
Run Code Online (Sandbox Code Playgroud)

然后我们的-initWithFrame:方法如下所示:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubviewFromNib];
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

只需确保nib与类的名称相同即可.


Jef*_*mas 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;
}
Run Code Online (Sandbox Code Playgroud)

它为您提供构建视图时似乎需要的灵活性,但不会导致内存泄漏或警告.