使用自定义XIB的自定义UIView的EXC_BAD_ACCESS

我正在开发一个iOS 5+应用程序与最新的SDK。

我用自定义的XIB创build了一个自定义的UIView( TopMenuView )。 在界面生成器我已经改变,在这个XIB, UIView类到TopMenuView 。 我没有设置任何File's Owner

TopMenuView.m我有:

 - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { NSLog(@"init with coder: %d", counter); counter++; // Add custom XIB NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil]; UIView *nv = [topMenuView objectAtIndex:0]; [self addSubview:nv]; } return self; } 

使用界面生成器我已经添加了一个UIViewUIViewController ,并将此UIView类更改为TopMenuView

但是,当我运行的应用程序,我得到这个日志消息4251倍: 2013-10-13 20:49:34.078 MyProject[470:c07] init with coder: 0

然后,我在这里得到一个EXC_BAD_ACCESS

 NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil]; 

这是我做到的:

 //Add Custom View to my main view of viewcontroller self.customNavView = [[CustomNavigationView alloc] init]; self.customNavView = [[[NSBundle mainBundle] loadNibNamed:@"CustomNavigationView" owner:self options:nil] objectAtIndex:0]; [self.customNavView setFrame:CGRectMake(0, 20, 320, 54)]; [self.view addSubview:self.customNavView]; 

这里CustomNavigationView是一个UIView子类,具有UIView文件所有者类和UIView自定义类作为CustomNavigationView。

这对我有用。

它调用initWithCoder这么多次的原因是由于错误的.xib文件中的类设置。

确保文件所有者上的自定义类是你自定义的UIView类:

在这里输入图像说明

并确保根视图上的类是默认的UIView:

在这里输入图像说明

现在,这是您的自定义类(在Swift中)所需的全部内容:

 required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) let view = NSBundle.mainBundle().loadNibNamed("TopMenuView", owner: self, options: nil)[0] as! UIView self.addSubview(view) view.frame = self.bounds } 

你很可能进入一个无限循环,因为你是recursion调用initWithCoder 。 一种解决方法是检查你的子类是否有任何子视图。

 -(id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { if (self.subviews.count == 0) { NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil]; UIView *nv = [topMenuView objectAtIndex:0]; [self addSubview:self.view]; } } return self; } 

你的- (id)initWithCoder:(NSCoder *)aDecoder被调用,只要通过加载你的xib创buildTopMenuView。

因此,你recursion地调用你的initWithCoder:


注释你所有的方法- (id)initWithCoder:(NSCoder *)aDecoder

以及您想在某些控制器中使用TopMenuView位置,请使用下面的代码

 NSArray *topMenuView = [[NSBundle mainBundle] loadNibNamed:@"TopMenuView" owner:nil options:nil]; UIView *nv = [topMenuView objectAtIndex:0]; 

我得到同样的错误,直到我redid如何从故事板加载xib文件。 基本上它涉及到从xib文件的根视图到代码的@IBOutlet。 另外请确保您将xib的文件所有者设置为您的自定义类。

 import UIKit class ResuableCustomView: UIView { @IBOutlet var view: UIView! @IBOutlet weak var label: UILabel! @IBAction func buttonTap(sender: UIButton) { label.text = "Hi" } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) NSBundle.mainBundle().loadNibNamed("ReusableCustomView", owner: self, options: nil)[0] as! UIView self.addSubview(view) view.frame = self.bounds } } 

我设置这个项目的完整答案就在这里 。