2

我收到以下错误

Property 'navigationController' not found on object of type

我继承了这个项目,不知道发生了什么。

在我的 didSelectRowAtIndexPath 文件中,我有

[self.navigationController pushViewController:nextController animated:YES];

在我访问应用程序委托导航控制器(即插座)之前,这不是问题。但是,我不得不放弃这种方法,因为它给我带来了问题。我已经转换了我的项目的其余部分。但是在这种情况下,项目没有使用普通的表格视图,导航控制器看起来不可用。我在其他 7 个视图中有这个问题。希望我能解决这个问题,并保持这个更干净的代码?

在此处输入图像描述 我对此感到非常困惑,我认为这是因为 SetsStyleSectionController 不是视图控制器而是 NSObject。

但是,即使将此设置为 UIViewController,代码也会运行,但也不会推送。将 SetsSectionController 从 NSObject 更改为 UIViewController 不可用。

我不确定如何进行?

我正在远离应用程序委托的推送。

编辑:下面讨论的屏幕截图 2 在此处输入图像描述

4

2 回答 2

1

我在这里看到了几个问题。您对协议和类有误解,并且您还有一个与协议接口的应用程序,虽然出于善意,但实际上使您的生活变得比需要的要困难得多。

您要处理的第一个问题是理解协议和类之间的差异,以及采用协议和从类继承之间的一些问题。这完全没问题,这东西不容易。基本上,协议只是对象的接口,而类既提供接口又提供实现。换句话说,协议只是可以调用的方法列表,而类既是方法列表又是执行这些方法的代码。要获得更完整的解释,也许您最好直接查看源代码 - 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考虑这些是否是正确的问题来询问负责单个表的单个部分的内容。如果您仍然想使用它,我认为需要进行一些重大的重构才能使其成为真正让您的生活更轻松而不是更难的形状。根据每个部分逻辑偏差的复杂性,我可能会完全放弃它。但这确实是另一个问题。希望这可以帮助!

于 2012-09-30T10:45:49.910 回答
1

你是什​​么意思它“不可用”?你的意思是你不想/不允许继承 UIViewController,或者你得到一个编译器错误?根据您对问题的评论:

SetsSectionController.h:12:34: Cannot find protocol declaration for 'UIViewController'

你正在改变错误的东西来改变你的子类。举个例子:

#import <Foundation/Foundation.h>

@protocol foo <NSObject>
- (void) bar;
@end

@interface lolcats : NSObject <foo>
@end

要更改您的超类,请在冒号后更改类名。前任。

@interface lolcats : NSObject <foo>

变成

@interface lolcats : UIViewController <foo>

你就跑起来了。但是,如果您不小心更改了协议的协议要求

@protocol foo <NSObject>

@protocol foo <UIViewController>

相反,或者更改您遵守的协议<UIViewController>,您最终会得到您得到的确切错误。你可能会感到困惑,因为协议说遵守它的对象也必须遵守 NSObject 协议,而 NSObject 也是一种对象。对象和协议是分开的东西,所有的对象都继承自NSObject,从而继承了协议。基本上,它是说“使用此协议的对象必须是对象”。

你为什么期望这会起作用?该对象只是一个标准的 NSObject,它声明它遵循包含一些方法的协议。为什么它会有一个导航控制器属性?它没有从任何东西继承它。无论如何,根据您的错误,您可能只是更改了错误的内容。确保在冒号后更改超类的类名。

于 2012-09-30T16:12:47.693 回答