我在这里看到了几个问题。您对协议和类有误解,并且您还有一个与协议接口的应用程序,虽然出于善意,但实际上使您的生活变得比需要的要困难得多。
您要处理的第一个问题是理解协议和类之间的差异,以及采用协议和从类继承之间的一些问题。这完全没问题,这东西不容易。基本上,协议只是对象的接口,而类既提供接口又提供实现。换句话说,协议只是可以调用的方法列表,而类既是方法列表又是执行这些方法的代码。要获得更完整的解释,也许您最好直接查看源代码 - Apple 的“Objective-C 编程语言”可能会对您有所帮助,因此请阅读那里的类和协议。我认为这样做你会明白为什么你id<SetSectionController>
navigationController
没有明确定义的属性。但是,如果您之后对此有具体问题,请告诉我。
更难解决的问题是这个SetSectionController
协议。它有几个问题,描述它们都超出了这个答案的范围。事情是这样的——实现基本上需要实现这个协议的对象来知道哪个导航控制器与表格视图相关联。到目前为止,这已经通过将它们耦合到应用程序的委托来提供deus ex machina,您可以删除这种耦合。但是现在您必须找到另一种方法来将正确的数据填充到视图控制器中,以将其推送到导航堆栈上。
我认为您应该将推送逻辑移动到视图控制器中,现在让节控制器提供一个接口,为视图控制器提供所需的信息。所以说部分控制器有一个像这样的伪代码的实现:
- (void)...didSelectRow...
{
id detailsForIndexPath = self.dataForRows[indexPath.row];
DetailViewController *vc = [DetailViewController new];
vc.details = detailsForIndexPath;
[APPDELEGATE.navigationController push:vc];
}
然后我会添加一个方法来SetSectionController
调用类似的东西-dataForRow:
,其实现就像上面方法的第一行一样。然后,在您的视图控制器中,...didSelectRow...
像这样实现:
- (void)...didSelectRow...
{
id<SetSectionController> sc = self.sectionControllers[indexPath.section];
id details = [sc dataForRow:indexPath.row];
DetailViewController *vc = [DetailViewController new];
vc.details = details;
[self.navigationController push:vc];
}
如果您的部分控制器正在做其他有用的事情,...didSelectRow...
请确保将其移动到视图控制器或...didSelectRow...
现在转发到部分控制器。
虽然我很欣赏尝试通过多态性使复杂的表部分更容易管理,但这个协议并不是正确的方法。它盲目地复制方法,UITableViewDelegate
而不UITableViewDataSource
考虑这些是否是正确的问题来询问负责单个表的单个部分的内容。如果您仍然想使用它,我认为需要进行一些重大的重构才能使其成为真正让您的生活更轻松而不是更难的形状。根据每个部分逻辑偏差的复杂性,我可能会完全放弃它。但这确实是另一个问题。希望这可以帮助!