2011-01-29 246 views
0

我是iPhone编程新手。我创建了一个基于窗口的应用程序。以下是我的代码:iphone应用程序崩溃

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    UILabel *myLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(50, 200, 200, 80)]; 
    myLabel1.text = @"Prasad"; 
    NSLog(@"myLabel retain Count: %d\n", [myLabel1 retainCount]); 
    [myLabel1 release]; 
    NSLog(@"myLabel retain Count: %d\n", [myLabel1 retainCount]); 
    [window makeKeyAndVisible]; 
    return YES; 
} 

Q1。当我释放mylabel1时,在release语句之后的NSLog语句仍然会打印retainCount为1,而理想情况下它应该打印0.此外,应用程序运行非常好。

现在考虑下面的代码:(这类似于上面的代码中,除了加入一个的NSLog声明:的NSLog(@ “Bingoooooooo Memeory被释放”);)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    UILabel *myLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(50, 200, 200, 80)]; 
    myLabel1.text = @"Prasad"; 
    NSLog(@"myLabel retain Count: %d\n", [myLabel1 retainCount]); 
    [myLabel1 release]; 
    NSLog(@"Bingoooooooo Memeory Released"); 
    NSLog(@"myLabel retain Count: %d\n", [myLabel1 retainCount]); 
    [window makeKeyAndVisible]; 
    return YES; 
} 

现在我的查询,
1 。当我运行上面的代码时,应用程序在打印NSLog(@“Bingoooooooo Memeory Released”)后崩溃;为什么应用程序只是通过添加NSLog(@“Bingoooooooo Memeory Released”)语句而崩溃,而在第一个代码中,应用程序不会崩溃。

+0

Prazi,请花时间在问题中正确地设置代码的格式,那么很有可能有人能够帮助您。 –

+0

发送您的应用程序崩溃报告。 – Tirth

+2

如果'retainCount'曾经返回零,那么奇点就会实现,宇宙就会结束。至少,它会用于你的应用程序。 – bbum

回答

1

的文档-retainCount有如下警告:

重要:这种方法通常是在调试内存管理问题没有价值的。因为任何数量的框架对象都可能保留了一个对象以保存对它的引用,同时autorelease池可能在对象上保存了任意数量的延迟发布,所以很难从此获得有用的信息方法。

而且,各种其他的答案大约保持在堆栈溢出计数说,不靠-retainCount


这就是说,回答你的问题:

Q1。当我释放mylabel1,继发布声明的NSLog声明仍然打印retainCount为1,而理想情况下,应打印0

让我们考虑你的对象是不是在一个自动释放池。如果对象保留计数1并收到release消息,则它将被解除分配。减少一个释放对象的保留计数有什么意义?运行时没有这样做,因为它是一个毫无意义的操作,因为对象已经不存在了。

1.当我运行上面的代码时,应用程序在打印NSLog(@“Bingoooooooo Memeory Released”)后崩溃了;为什么应用程序只是通过添加NSLog(@“Bingoooooooo Memeory Released”)语句而崩溃,而在第一个代码中,应用程序不会崩溃。

首先,请注意,由于myLabel1未被其他对象/代码所有,因此当您发送[myLabel1 release]时,它将被释放。如果您将更多消息发送到解除分配的对象(例如[myLabel1 retainCount]),您的代码可能会崩溃,所以不要这样做。

当一个对象被释放时,对象占用的内存被标记为可用。根据随后的指令,先前由对象占用的内存区域可能会或可能不会被重写。在重写之前,可以引用解除分配的对象 - 它是一个鬼对象,并且根本不可靠。在你的情况下,添加另一个NSLog()指令或其他因素会导致该内存区域被重写。

4

首先,永远不要看retainCount。它不可靠,并受很多内部因素的影响。代码的第二个版本会导致崩溃,因为: 1)您创建一个标签,使其保留计数为1 2)您释放它以使其保留计数为0 3)您向其发送消息。由于其保留计数为0,因此它已被释放,所以应用程序崩溃。

不知道为什么第一个版本不崩溃

+0

@Prazi查看Dave Delong的答案http://stackoverflow.com/questions/4636146/when-to-use-retaincount/4636477#4636477 – Robin