2012-09-29 38 views
2

我收到以下錯誤Obj-C,Property'navigationController'找不到類型的對象,從NSObject類?

Property 'navigationController' not found on object of type 

我繼承了這個項目,不知道發生了什麼事情。

在didSelectRowAtIndexPath方法我M檔我有

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

這不是一個問題之前,我正在訪問應用程序的委託導航控制器,這是出口。但是,我不得不擺脫這種方式,因爲它會導致我的問題。我已經轉換了我的項目的其餘部分。但在這種情況下,如果項目沒有使用正常的表格視圖,導航控制器看起來並不可用。我在其他7個觀點中有這個問題。希望我能解決這個問題,並保持這個更清潔的代碼?

enter image description here 我真的被這個困惑,我覺得這是發生爲SetsStyleSectionController不是一個視圖控制器,但是NSObject的。

但是,即使將此設置爲UIViewController,代碼也會運行,但不會推送。 將SetsSectionController從NSObject更改爲UIViewController不可用。

我不確定如何繼續?

我正在擺脫從應用程序代理推送的過程。

編輯:截圖2討論下面 enter image description here

+1

您的項目是否有UINavigationController? –

+0

是的和一個tabbarcontroller。這些類旨在使其更清潔以生成表格視圖。 – Jules

+1

爲什麼不使用'UITableViewDelegate'而不是'SetsSectionController'? 你是什麼意思 「將SetsObject控件從NSObject更改爲UIViewController不可用」? 'SetsStyleSectionController'是否有一個名爲'navigationController'的屬性? –

回答

1

我看到一對夫婦的問題在這裏。你對協議和類有誤解,你也有一個與協議接口的應用程序,雖然善意實際上讓你的生活比需要的更難。

你遇到的第一個問題是一些煩惱協議和類之間以及採用協議和從類繼承之間的區別。這很好,這個東西不容易。基本上,協議只是一個對象的接口,而一個類提供了一個接口和一個實現。換句話說,協議只是一個可以調用的方法列表,而一個類既是方法列表,也是執行這些方法的代碼。爲了得到更完整的解釋,或許你會更好地直接找到源代碼 - 蘋果公司的"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

你是什麼意思「不可用」?你的意思是你不想/不允許繼承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,它聲明它遵守一個包含幾個方法的協議。爲什麼它會有一個導航控制器屬性?它沒有從任何東西繼承它。無論如何,根據你的錯誤,你可能只是改變了錯誤的東西。確保在冒號後更改超類的名稱。

+0

我已經爲我的問題添加了屏幕截圖,包括嘗試更改協議時的錯誤。我將從NSObject更改爲UIViewController。如果我將其更改回NSObject,則所有內容都會運行,但推送不起作用,並且沒有錯誤。我不確定是否有我沒有回答的問題? – Jules

+0

@Jules代言是正確的。問題是「UIViewController」是一個對象或類而不是協議。這就是爲什麼你得到「無法找到協議聲明...」錯誤(第一張截圖)。看起來你甚至不需要創建「SetsSectionController」協議,因爲「UITableViewDelegate」已經有你正在創建的方法定義。另外,UITableViewController已經符合UITableViewDelegate協議。刪除SetsSectionController.h文件,並從SetsStyleSectionController.h文件中刪除「」和導入。 – RyanM

+0

@Jules你有沒有把超類聲明與協議需求混淆?你的對象只是一個普通的'NSObject',在協議中聲明瞭一些額外的方法;不知道你的期望。它不是'UIViewController'或'UITableViewController'子類。看起來你試圖改變它繼承的類,但是你在錯誤的地方做它。最初的「未找到屬性」錯誤源於以下事實:您或者對您有參考的事情可能嘗試訪問'navigationController'屬性,而這對於普通的'NSObject'子類是不可用的。 – Metabble

相關問題