我创建了两个不同的子视图EPStudentProgressOpenQuestion
和EPStudentProgressMultipleChoiceQuestion
。它们都继承自EPStudentProgressQuestion
,因为它们的子视图共享一些共同的信息和行为。
每个视图都有自己的XIB文件。
在EPStudentProgressQuestion
内,有以下代码:
#import "EPStudentProgressQuestion.h"
@interface EPStudentProgressQuestion ()
@property (assign, nonatomic) EPStudentProgressQuestionType questiontype;
@end
@implementation EPStudentProgressQuestion
#pragma mark - UIView lifecycle
- (instancetype)initWityQuestionType:(EPStudentProgressQuestionType)questionType {
self = [super init];
if (self) {
self.questiontype = questionType;
[self setupView];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setupView];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self setupView];
}
return self;
}
#pragma mark - Private methods
- (void)setupView {
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
UIView *view = [[bundle loadNibNamed:[self nibNameForQuestionType] owner:[self class] options:nil] firstObject];
view.frame = self.bounds;
[self.layer setCornerRadius:2.f];
[self.layer setBorderWidth:1.f];
[self.layer setBorderColor:[UIColor colorWithWhite:232/255.f alpha:1.f].CGColor];
[self setClipsToBounds:YES];
[self setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:view];
}
- (NSString*)nibNameForQuestionType {
switch (self.questiontype) {
case EPStudentProgressQuestionTypeOpen:
return @"EPStudentProgressOpenQuestion";
case EPStudentProgressQuestionTypeMultipleChoice:
return @"EPStudentProgressMultipleChoiceQuestion";
}
}
如您所见,非常简单的代码。
如上所述,每个EPStudentProgressQuestion
视图都有自己的XIB文件,将Files Owner
连接到Identity Inspector
类。
这是EPStudentProgressOpenQuestion
:
#import "EPStudentProgressOpenQuestion.h"
@interface EPStudentProgressOpenQuestion ()
@property (weak, nonatomic) IBOutlet UILabel *lblQuestion;
@end
@implementation EPStudentProgressOpenQuestion
@end
EPStudentProgressMultipleChoiceQuestion
只是没有任何IBOutlet
完全相同。但是,只要我为其中任何一个视图创建IBOutlets
,我就会收到错误... IBOutlet is not key-value compliant...
没有IBOutlets
一切正常。每个视图都正确加载,并且它很好地放置在我想要的视图中。但是只要我将一些IBOutlets
从XIB链接到相应的类,就会崩溃......
这是崩溃:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<EPStudentProgressQuestion 0x1020196b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key lblQuestion.'
这就是我实例化EPStudentProgressQuestion
视图的方式:
EPStudentProgressOpenQuestion *questionView = [[EPStudentProgressOpenQuestion alloc] initWityQuestionType: EPStudentProgressQuestionTypeOpen];
[self.vQuestionsContainer addSubview:questionView];
关于如何能够在没有问题的情况下链接IBOutlets
的任何想法?
提前谢谢!!
修改
如果我按如下方式更改bundle
和owner
类:
NSBundle *bundle = [NSBundle bundleForClass:[EPStudentProgressOpenQuestion class]];
NSArray *views = [bundle loadNibNamed:[self nibNameForQuestionType] owner:[EPStudentProgressOpenQuestion class] options:nil];
UIView *view = [views firstObject];
我收到了同样的错误,但我没有EPStudentProgressQuestion
而是EPStudentProgressOpenQuestion
错误...
编辑2: 测试项目链接:https://mega.nz/#!oBhWkawC!RSOzrPOfq_UTVWd3jraRkneuCIyIkS61PKGeca2Bilc
答案 0 :(得分:0)
您的视图控制器可能在您的xib中有错误的类。请更改UIView类名称,而不是像文件
中的文件所有者您还在:
中调用了[self setup]方法- (instancetype)initWityQuestionType:(EPStudentProgressQuestionType)questionType {
self = [super init];
if (self) {
self.questiontype = questionType;
[self setupView];
}
return self;
}
您不需要再次拨打电话
- (instancetype)initWithFrame:(CGRect)frame {
}
和
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
}
它正在创建一个init循环并导致内存泄漏。
答案 1 :(得分:0)
您的崩溃表明EPStudentProgressQuestion
(您的超类)不符合键值。这意味着在您访问IBOutlet时,您引用EPStudentProgressQuestion
而不是EPStudentProgressOpenQuestion
或EPStudentProgressMultipleChoiceQuestion
。
只需检查您使用新IBOutlets的代码,并更改其中使用的变量类型或将强制转换添加到正确的类。
答案 2 :(得分:0)
让您崩溃的问题是,您正在传递[self class]
而非self
作为笔尖所有者。将你的笔尖加载线更改为:
NSArray *views = [bundle loadNibNamed:[self nibNameForQuestionType] owner:self options:nil];
你还有另一个问题,那就是你要两次加载笔尖。在initWityQuestionType:
中,您拨打[super init]
。你没有意识到的是-[UIView init]
来电[self initWithFrame:CGRectZero]
。因此,您最终会调用被覆盖的initWithFrame:
,并调用setupView
。然后,当它返回initWityQuestionType:
时,也会调用setupView
。
我建议你完全摆脱initWithFrame:
覆盖。