2011-08-28 52 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被保留,从而摆脱了崩溃。

相关问题