Obj-C,属性'navigationController'在NSObject类的类型对象上找不到?

时间:2012-09-29 22:17:02

标签: iphone objective-c ios xcode

我收到以下错误

Property 'navigationController' not found on object of type

我继承了这个项目并且不确定发生了什么。

在didSelectRowAtIndexPath的m文件中,我有

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

在我访问app delegate导航控制器(这是出口)之前,这不是问题。但是,我不得不放弃这种方法,因为它会给我带来麻烦。我转换了我的项目的其余部分。但是在这种情况下,如果项目没有使用普通的表视图,导航控制器看起来不可用。我在其他7个视图中有这个问题。希望我能解决这个问题,并保持这个更清洁的代码吗?

enter image description here 我真的对此感到困惑,我认为这是因为SetsStyleSectionController不是视图控制器而是NSObject。

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

我不确定该怎么办?

我正在逐渐远离推销应用代表。

编辑:下面讨论的屏幕截图2 enter image description here

2 个答案:

答案 0 :(得分:1)

我在这里看到了几个问题。你对协议和类有一个误解,你也有一个与协议接口的应用程序,虽然善意实际上让你的生活变得比它需要的更难。

您正在处理的第一个问题是解决协议和类之间的差异,以及采用协议和继承类之间的一些问题。哪个完全没问题,这个东西并不容易。基本上,协议只是对象的接口,类提供接口和实现。换句话说,协议只是可以调用的方法列表,类是方法列表和执行这些方法的代码。为了得到更完整的解释,也许你最好直接找到源码 - Apple的"The Objective-C Programming Language"可能会帮助你,所以请阅读那里的类和协议。我认为这样做了,你就会明白为什么你没有成功地为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...转发至部分控制器。

虽然我很欣赏尝试通过多态来更容易地管理复杂的表格部分,但是这个协议并不是正确的方法。它盲目地从UITableViewDelegateUITableViewDataSource复制方法,而不考虑这些是否是对单个表的单个部分负责的问题的正确问题。如果您仍然想要使用它,我认为需要进行一些重要的重构才能使它变成一种实际上让您的生活更轻松而不是更难的形状。根据每个部分逻辑偏差的复杂程度,我可能会完全废弃它。但这确实是另一个问题。希望这有帮助!

答案 1 :(得分:1)

你是什么意思&#34;不可用&#34;?你的意思是你不想让/不允许继承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,因此继承了协议。基本上,它说&#34;使用此协议的对象必须是对象。&#34;

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