我有一个类 FooView
,它是 UIView
的子类,其视图是从一个nib加载的,类似于:
+ (instancetype)viewFromNib
{
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:@"FooView" owner:self options:nil];
return [xib objectAtIndex:0];
}
nib本身在Identity Inspector中将其Custom Class设置为 FooView
.
这被实例化为:
FooView *view = [FooView viewFromNib];
这表现得像你期望的那样 . 但是,当FooView本身被子类化为FooSubclassView,并实例化为:
FooSubclassView *view = [FooSubclassView viewFromNib];
view
仍然是 FooView
类型,而不是 FooSubclassView
.
使用 object_setClass
对类进行调配并不能解决基础对象是 FooView
的实例的问题,因此在子类实例上调用的方法将是超类( FooView
)的方法,而不是 FooSubclassView
.
我如何纠正这一点,以便子类具有正确的类型,而不必为每个子类创建一个新的nib,或者必须在每个子类中重新实现 viewFromNib
?
2 回答
调酒不是(永远)的答案 .
问题出在你的NIB上;它被归档,对象[0]是
FooView
的一个实例,而不是FooSubclassView
. 如果要将具有不同视图子类的相同NIB作为对象[0]加载,则需要将实例移出NIB的存档 .可能是最简单的事情,因为你的类已经加载了NIB,所以要创建
FooView
或FooSubclassView
文件所有者的实例 .这个问题对File的Owner模式有一个很好的解释 . 请注意,您几乎已经在那里,因为您的类无论如何都在加载XIB / NIB .
这是官方的docs on File's Owner .
我不确定你是不是最好的解决方案,但我认为这正是你要找的 .
只要您可以确定NIB与该类具有相同的名称即可 .
在意识到我误解了其中一个要求后,我说我必须同意@bbum .