uncaught exception 'NSInternalInconsistencyException, reason:[UITableViewController loadView] loaded the "Controller" nib but didn't get a UITableView


http://blog.csdn.net/ryantang03/article/details/7941058#reply

上面那篇文章是我查找的ios實現下拉刷新功能,在我下載完代碼運行的過程中發現會報下面的這個錯誤。經過半下午的研究我終於找到了原因。

EGOTableViewPullRefreshTest[2150:907] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UITableViewController loadView] loaded the "MainViewController" nib but didn't get a UITableView.'

1.我找到的第一個解決辦法就是在該網站下的一個評論:http://t6883.codeinpro.us/q/50810b8b4f1eba38a4f10fe6

If you subclass a UITableViewController on purpose, you need to change it's default view load behaviour just by overriding it's load view method:

- (void)loadView {
    [super loadView];
}

加到代碼中果然可以了,由於不知道原因,又查找了一下loadView的作用,現附文章如下:

http://www.dreamingwish.com/dream-2011/correct-online-information-error-loadview-viewdidload-viewdidunload.html

一、loadView

永遠不要主動調用這個函數。view controller會在view的property被請求並且當前view值為nil時調用這個函數。如果你手動創建view,你應該重載這個函數。如果你用IB創建view並初始化view controller,那就意味着你使用initWithNibName:bundle:方法,這時,你不應該重載loadView函數。

這個方法的默認實現是這樣:先尋找有關可用的nib文件的信息,根據這個信息來加載nib文件,如果沒有有關nib文件的信息,默認實現會創建一個空白的UIView對象,然后讓這個對象成為controller的主view。

所以,重載這個函數時,你也應該這么做。並把子類的view賦給view屬性(property)(你create的view必須是唯一的實例,並且不被其他任何controller共享),而且你重載的這個函數不應該調用super。

如果你要進行進一步初始化你的views,你應該在viewDidLoad函數中去做。在iOS 3.0以及更高版本中,你應該重載viewDidUnload函數來釋放任何對view的引用或者它里面的內容(子view等等)。

這個網上的資料都說的很不全面,尤其是藍色字部分。

二、viewDidLoad

這個函數在controller加載了相關的views后被調用,而不論這些views存儲在nib文件里還是在loadView函數中生成。而多數情況下是做nib文件的后續工作。

網上資料對這個函數的描述則完全不對。

三、viewDidUnload

這個函數是viewDidLoad的對立函數。在程序內存欠缺時,這個函數被controller調用()。由於controller通常保存着與view(這里黑體的view指controller的view屬性)相關的對象(一般是view的子view)或者其他運行時創建的對象的引用,所以你必須使用這個函數來放棄這些對象的所有權以便內存回收。但不要釋放那些難以重建的數據(不要在這個函數中釋放view)。

通常controller會保存nib文件建立的views的引用,但是也可能會保存着loadView函數創建的對象的引用。最完美的方法是使用合成器方法:

self.myCertainView = nil;

這樣合成器會release這個view,如果你沒有使用property,那么你得自己顯式釋放這個view。

網上對這個函數的描述含含糊糊,看了等於沒看。

另外:如果controller存儲了其他object和view的引用,你還得在dealloc方法中釋放這些內存。對於iOS2.x,你還必須在調用super dealloc方法前將這些引用置為nil。

四、結論

所以流程應該是這樣:

(loadView/nib文件)來加載view到內存 ——>viewDidLoad函數進一步初始化這些view ——>內存不足時,調用viewDidUnload函數釋放views

—->當需要使用view時有回到第一步

如此循環

2.后來我又無意中看到我我前幾天寫的下面這篇文章是,帶顏色的部分是我着重標出的(前幾天剛寫,里面的重要問題就忘記了,看來非得被問題拌一腳才能長記性😄)

http://www.cnblogs.com/baozou/p/3314578.html

UITableViewController繼承自UIViewController,但是initWithNibName:bundle:方法的行為是不一樣的。普通的UIViewController如果nibName參數是nil,則自動載入和自己類名相同的xib文件。而UITableViewController遇到nibName為nil時,卻不加載xib文件,而是創建一個空的table view。所以,對於UITableViewController來說,如果使用了xib文件,則必須寫出完整xib文件名,才能正確創建。

因此,當使用了xib時,UITableViewController不能使用這樣的方式創建:

[[TableViewController alloc] init];
[[TableViewController alloc] initWithNibName:nil bundle:nil];

然后我在appdelegate里面果然找到這樣的代碼:

MainViewController *mainView = [[MainViewControlleralloc] init];看來果真是這個原因。

3.還有一種方法

下拉刷新的那個例子是定義的類直接繼承自UITableViewController 而 我以前遇到的情況都是繼承自UIViewController 然后在類中定義一個UITableView。

其實要理解這幾個類之間的關系就好辦了,我就是不明白這幾個類之間的關系才出錯。

UITableViewDelegate 

UITableViewDataSource這兩個代理是在UITableView中定義的,然后放到了UITableView類中來使用,UITableViewController類包含UITableView類變量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM