【问题标题】:EXC_BAD_ACCESS in main( )main() 中的 EXC_BAD_ACCESS
【发布时间】:2012-03-31 11:15:19
【问题描述】:

我在main() 中有一个EXC_BAD_ACCESS,这是我的代码:

int main(int argc, char *argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, @"TestBedAppDelegate");
    [pool release];
    return retVal;
}

@interface TestBedAppDelegate : NSObject <UIApplicationDelegate>
@end

@implementation TestBedAppDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[[TestBedViewController alloc] init]];
    [window addSubview:nav.view];
    [window makeKeyAndVisible];
}
@end

- (void) action: (id) sender
{
    [self highRetainCount];
}

@implementation TestBedViewController
- (void) highRetainCount
{
    UIView *view = [[[UIView alloc] init] autorelease];
    printf("Count: %d\n", [view retainCount]);

    NSArray *array1 = [NSArray arrayWithObject:view];
    printf("Count: %d\n", [view retainCount]);
    [array1 autorelease]; // If comment this line, everything will be OK
}
@end

程序停在main():

int retVal = UIApplicationMain(argc, argv, nil, @"TestBedAppDelegate");

正如评论所说,注释掉[array1 autorelease];后,一切正常。

所以这是我的问题:

  1. EXC_BAD_ACCESS 通常表示使用已释放的对象。显然和[array1 autorelease];有关系,但我无法理解他们的关系。

  2. 为什么停在这个位置——main()——而不是其他地方?

新手问题:)

【问题讨论】:

  • array1 已经自动释放,因此调用autorelease 会让一切都崩溃。
  • Saphrosit 是对的,你不需要调用 [array1 autorelease];
  • 它不是“已经自动发布”,它不属于调用者。有区别(尽管对于外部观察者来说,两者可能看起来相似)。
  • @HotLicks - 不,确实没有,请阅读我的答案中的文档链接。它返回调用者不拥有的NSArray*。可能是实现创建了一个NSArray,自动释放它并返回它,但也可能实现只是返回一个指向现有实例的指针。 API 指定的只是缺乏所有权;您正在就实施提出声明。
  • @HotLicks 当现有实例由被调用者拥有时,请参见内部记忆

标签: objective-c ios cocoa


【解决方案1】:

arrayWithObject: 返回一个您不拥有的对象。因此,您随后发送autorelease是错误的。

Basic Memory Management Rules,具体来说:

  • 您不得放弃不属于您的对象的所有权

  • 您拥有自己创建的任何对象

您使用名称以“alloc”、“new”、“copy”或“mutableCopy”开头的方法创建对象(例如,allocnewObjectmutableCopy)。

另外,一般来说,不要使用retainCount。除非您碰巧对运行时进行低级黑客攻击或其他什么,否则您不需要它,它也不会返回任何有用的东西。

【讨论】:

  • retainCount 在尝试诊断存储问题时有时很有用,但正如您所建议的,永远不应该在“真实”代码中使用。
  • 我还没有看到有人尝试这样做而不依赖于各种无效但偶尔巧合的例子
  • 我曾多次使用它来解决存储问题。你只需要先了解它是如何工作的。
  • 我说如果你真的了解它是如何工作的,你就不会使用它,c.f. friday.com/bbum/2011/12/18/retaincount-is-uselessstackoverflow.com/questions/5784084/…
  • 如果您知道它是如何工作的,那么您就知道使用retainCount 是在浪费时间,因为有一种更好的方法需要更少或不需要代码......
猜你喜欢
  • 2012-03-01
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多