2011-08-28 36 views
0

我試圖從WWDC 2010 vol128掌握表視圖合併和修改擴展節頭。但是,我必須錯過一個步驟或忘記了一些內容,因爲我在嘗試使用表視圖訪問我的視圖時遇到了EXC_BAD_ACCESS錯誤。我得到EXC_BAD_ACCESS試圖使用我的UITableViewController的子類

我忘了你在哪裏可以找到源代碼,但它在他們的開發者網站上。這是很多的代碼發佈。

我看到的主要區別是他們的版本將UITableViewController的子類作爲子視圖添加到它們的appdelegate即。窗口。我想將我的控制器添加到viewviewler中的scrollview。我確定有這個問題嗎?

下面的原始代碼對我來說沒有任何意義,因爲它在將它添加爲子視圖之前釋放aTableViewController,在我的版本中,我無法做到這一點。它也使得self.tableViewController = aTableViewController; tableViewController是這樣合成在頂部: @synthesize tableViewController=tableViewController_我不知道它來自哪裏,因爲它沒有在項目中的任何其他地方引用。同樣,原始代碼在應用程序代碼中也有這樣的代碼,所以也許有些東西我不知道在那裏發生。

蘋果的代碼(它的工作原理):

TableViewController* aTableViewController = [[TableViewController alloc] initWithStyle:UITableViewStylePlain]; 
    aTableViewController.plays = self.plays; 
    self.tableViewController = aTableViewController; 
    [aTableViewController release]; 

    // Stamdard window display. 
    [self.window addSubview:aTableViewController.view]; 
    [self.window makeKeyAndVisible]; 

出於測試目的,我做了一個空testTableViewController子這幾乎是空的,並試圖將其添加爲具有相同結果的子視圖。也許,我錯誤地創建了一個UITableViewController子類。對不起,因爲含糊不清,但我認爲它與上面給出的信息片斷有關。

謝謝

+0

你提到這行代碼:'@synthesize tableViewController = tableViewController_'。你還可以粘貼屬性聲明,該聲明應該如下所示:'@property(nonatomic,retain)tableViewController;' – Steve

+0

另外,請粘貼代碼行(以及某些上下文),以獲取錯誤。 – Steve

+0

嗯,我完全忘了那個。謝謝。它不再崩潰。我仍然好奇爲什麼self.tableViewController = aTableViewController允許我在將它添加爲子視圖之前釋放一個TableViewController。 – Adam

回答

0

要回答這個問題:

下原來是沒有意義的我,因爲它增加它作爲一個子視圖

你提到之前釋放 aTableViewController:

它也使self.tableViewController = aTableViewController; tableViewController像這樣在頂部合成:@synthesize tableViewController = tableViewController_我不知道它來自哪裏 ,因爲它沒有在項目的其他任何地方引用。

最有可能的,如果你在頭文件看,你會看到這樣一行:

@property (nonatomic, retain) tableViewController; 

這是一個「聲明的屬性」在Objective-C。已聲明的屬性提供了一種超級方便的方式來獲取/設置具有常見模式的ivars(例如保留分配給它們的任何值)。

從文檔:

Objective-C的聲明屬性功能提供了一種簡單的方法來 聲明和實現對象的存取方法。

你一定要在這裏看了介紹文檔:

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html

屬性包了一堆常見的模式的嘗試和真實的方式。

例如,考慮別人的(幼稚)可能實現的自動保留分配給它的值是setter方法:

- (void) setSomeIvar:(SomeObject *)value 
{ 
    [ivarValue release]; 
    ivarValue = [value retain]; 
} 

這似乎是確定在乍看之下,但考慮下面的代碼片段:

1: SomeObject * foo = [SomeObject new]; 
2: [bar setSomeIvar:foo]; 
3: [foo release]; 
... 

(後,潛在地在其他一些方法中,其中,foo是與上述相同的富):

4: [bar setSomeIvar:foo]; 

這裏會發生什麼?那麼,在第1行中,保留計數是+1,在第2行中,它是+2,第3行,+1,然後在第4行中,我們無意中釋放了該對象,然後我們將其分配給伊娃,並保留它,所以這段代碼會在該行發生錯誤。

的更正確的代碼會是這樣的:

- (void) setSomeIvar:(SomeObject *)value 
{ 
    if (ivarValue == value) return; 
    [ivarValue release]; 
    ivarValue = [value retain]; 
} 

然而,模式超越連這個簡單的例子。

所以,屬性是非常方便的,並將所有這些複雜性都包含進了更可靠,更可讀的東西中。

他們也使得它更容易確保你釋放你應該在你的dealloc方法中的一切。只需查看標記文件中標記的所有屬性(... retain ...)並確保它們在dealloc中發佈。此外,對於特別是UIViewController及其子類,在viewDidUnload中應將所有標記爲IBOutlet的保留屬性設置爲nil

當我第一次開始使用Objective-C時,我並沒有真正使用屬性 - 而且我爲此付出了代價。一旦我瞭解了他們並開始使用他們,他們讓我的生活變得更加輕鬆。

0

視圖控制器不保留他們的觀點;除其他原因外,這可以防止導致釋放問題的循環引用。 :]你必須自己保留視圖控制器。如果你聲明的屬性(self.tableViewController)沒有保留VC,你會將視圖添加到窗口,但是VC(視圖的一堆事件代表!)將被釋放,然後你會隨機獲得EXC_BAD_ACCESS。

你在你的問題中包含的代碼看起來像你的VC會在你將視圖添加到窗口之前被釋放。我猜你通過修復該屬性來確保VC被保留,從而擺脫了崩潰。

相關問題