使用.xib和支持类初始化UIView的正确方法
我有一些使用.xib文件进行布局的自定义创建的UIViews,以及用于额外安装的支持类。我使用alloc/init创建这些类,并在我的自定义init方法中调用loadNibNamed,但这样做会导致内存泄漏。有人指出,页头部分实际上创造了漏水所以自对象我调整我的init方法来这样一句:使用.xib和支持类初始化UIView的正确方法
- (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 ...]'“的结果。所以我的问题是什么是做一个支持类的自定义UIViews的正确方法?
既然有人问我会用这上面的代码是这样的:
AssignmentView * assignmentView = [[AssignmentView alloc] init];
[self.view addSubview:assignmentView];
从视图 - [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;
}
只要确保笔尖具有相同的名称这个班的工作。
另一个有趣的解决方案。我喜欢这个,因为我不必改变我已经在使用我的观点 – 2012-08-17 17:56:12
我知道这是旧的,但这是一个很好的解决方案,正是我希望做的。 – Armand 2017-08-11 04:42:24
你会考虑使用便利的构造风格吗?
+ (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-17 17:52:33
一般来说,如果你从xib载入一个视图,你应该通过'loadNibNamed'在你创建它的任何类中加载它,然后在它的'awakeFromNib'方法中设置它,甚至不用接触'init' 。无论如何,这是我的经验。你可能在实例化视图的时候添加一些代码,以及你的'awakeFromNib'方法吗? – 2012-08-16 19:26:33
我想你会在你的方法的顶部添加'self = [super init]'。保罗是对的,因为你通常不会在内部进行笔尖加载。 – Dustin 2012-08-16 19:26:45
谢谢,我一直试图避免整个loadNibNamed,只是使用[[MyView alloc] init],但如果我不得不重新工作,而是使用loadNibNamed,那么我想我必须。我没有一个awakeFromNib方法,但init中的所有内容都会去那里。 – 2012-08-16 23:31:48