0

我在与 NSURLConnection 和更普遍的 SIGABRT 调试有关的帖子上搜索了很多,但对此并不满意。任何帮助是极大的赞赏。

因此,在我的应用程序开始时,用户会看到一个登录视图,并在提供用户名和密码时,我通过在 LoginService 类中执行以下操作来启动 NSURLConnection:

-(void)loginWithURLRequest:(NSString*)requestString
{
    if(self.mConnection == nil)
    {
        NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestString]
                                                 cachePolicy:NSURLRequestUseProtocolCachePolicy
                                             timeoutInterval:120.0];

        self.mConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
    }
}

-(void)discardLoginDataAndPrepareToReceiveMore
{
    // Releases old mLoginData and assigns a new empty one.
    self.mLoginData = [[NSMutableData alloc] init];
}

-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
    [self discardLoginDataAndPrepareToReceiveMore];
}

-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
    [mLoginData appendData:data];
}

-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
    [self discardLoginDataAndPrepareToReceiveMore];
    [mDelegate onLoginFailure:error];

    self.mConnection = nil;
}

-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{   
    [mDataReader performSelector:mDataReaderSelector withObject:mLoginData];
    [mDelegate onLoggedInSuccessfully];

    self.mConnection = nil;
}

所以这一切都很好。问题是稍后我尝试 POST 一个请求(来自不同的类中),不久之后,应用程序在一个单独的线程上的程序集负载中使用 SIGABRT 崩溃,我无法追溯到我的代码。我意识到 NSURLConnection 是在另一个线程等上运行的。

所以我认为我的邮政编码可能有问题,并将其替换为下面完全相同的登录连接代码:

    NSString* requestString =  @"identical URL as before in login";

    NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestString]
                                             cachePolicy:NSURLRequestUseProtocolCachePolicy
                                         timeoutInterval:120.0];

    self.mConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];

同样的问题,所以我最后一次尝试是查看第一次登录是否以某种方式搞砸了。即,也许我对连接一无所知,并且没有正确清理等。所以我禁用了第一次登录并留下了我的第二次登录,然后它工作正常,我在委托方法等中获得了回调。

关于我可能做错的任何提示。在第一次连接期间/之后,我似乎没有做某事导致第二次连接崩溃。

当第一次登录仍然存在时,我可以跳过应用程序中的第二个 NSURConnection。在建立此连接后告诉应用程序继续后不久,就会发生实际崩溃。

在这两种情况下,mConnection 分别是每个类的(非原子的,保留的)属性。

我意识到有更好的方法来处理多个连接(在我四处搜索之后),无论如何我都需要尽快使用它们,但我需要让它为客户的演示工作,并且我也很好奇出了什么问题情况下,这意味着我对连接等有更根本的误解。

嗯,我想我也缺乏关于如何调试它的知识。对此的任何仪器提示将不胜感激。我避免在性能工具中使用分配,因为如果我的理解正确,SIGABRT 不是由泄漏引起的问题?

另外这里是调用堆栈:

-#0 0x90d7e132 in kill
-#1 0x90d7e124 in kill$UNIX2003
-#2 0x90e108e5 in raise
-#3 0x90e2699c in abort
-#4 0x90d23d35 in free
-#5 0x026fc081 in __CFStringDeallocate
-#6 0x026fbccb in _CFRelease
-#7 0x02720c9d in _CFAutoreleasePoolPop
-#8 0x0004fe67 in -[NSAutoreleasePool release]
-#9 0x00300e7f in _UIApplicationHandleEvent
-#10 0x030c4822 in PurpleEventCallback
-#11 0x027c5ff4 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION

-#12 0x02726807 in __CFRunLoopDoSource1
-#13 0x02723a93 in __CFRunLoopRun
-#14 0x02723350 in CFRunLoopRunSpecific
-#15 0x02723271 in CFRunLoopRunInMode
-#16 0x030c300c in GSEventRunModal
-#17 0x030c30d1 in GSEventRun
-#18 0x00304af2 in UIApplicationMain
-#19 0x0000242c in main at main.m:14

我认为这意味着(当我还查看下面的评论时)我在发布之前没有在某些东西(可能是字符串)上调用 alloc?

4

3 回答 3

0

如果没有完整的源代码,很难确定它,但看起来您正在调用 NSString 对象的第二个(并且无效的)版本。看看你在整个项目中是如何处理字符串的。确保它们在您的属性声明中具有“复制”属性,并且您不会不必要地释放已经自动释放的属性。(即创建了 [NSString stringWithFormat:] 的那些)

于 2010-11-22T14:22:36.560 回答
0

在启用 Zombie 后修复(我认为只跟踪泄漏而不是双重释放/自动释放)。我正在自动释放一个不需要它的字符串。

感谢 TomDalling 和 drowntoge,你们都走在了正确的轨道上。我刚到那里然后看到你的答案(当我发布这个时),无论如何这肯定会让我很快到达那里。我不知道 stringWithFormat 自动发布并且无论如何都在自动发布。只是真正开始使用自动释放并用于分配给本地人并在将所述本地分配给我的保留属性后释放它们。这也很好,只是代码不那么整洁。我想在我不知道之前我有很多泄漏。前段时间我读过关于内存的文档,但从未使用过自动释放,所以我想我需要再次回顾它们:-)

仍然不知道初始连接在启用时如何表现出问题,因为第二次连接是很晚的。完全把我扔了,因为我认为这完全是关于我对联系的理解。不过,有问题的字符串在此代码中及其周围。嗯,无论如何,欢呼伙计们。

于 2010-11-22T15:08:26.157 回答
0

您是否在启用僵尸的情况下运行您的应用程序?这可能是过度释放,僵尸会捡起。

跟踪此问题的另一种方法是启用 malloc 历史记录,并检查错误指针(您的评论中的 0x818c0b0)来自何处。

这可能对您有用:iPhone - 调试“未分配指针”错误

看起来好像内存在CFString/NSString对象内被破坏了,这意味着它可能发生在看起来完全不相关的某个地方。您可能将错误的指针传递给NSString,因此您可能也想检查一下。

还有,价值是mDataReaderSelector多少?如果您执行 aperformSelector:并且该方法返回一个可能损坏内存的结构(例如 NSRect)。这是一个很长的镜头,但我想我还是会检查一下。

于 2010-11-22T13:49:19.247 回答