第二次使用NSURLConnection会导致SIGABRT iPhone

时间:2010-11-22 10:06:17

标签: cocoa nsurlconnection sigabrt

我在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一个请求(来自不同的类),不久之后,应用程序在一个单独的线程上的程序集加载中崩溃,我无法追溯到我的代码。我意识到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    - #$ 0x90d7e124 in kill $ UNIX2003
   - #2 0x90e108e5在加注中    - #3 0x90e2699c中止
   - #4 0x90d23d35免费
   - __CFStringDeallocate中的#5 0x026fc081
   - 在_CFRelease中#6 0x026fbccb    - _CFAutoreleasePoolPop中的#7 0x02720c9d
   - #8 0x0004fe67 in - [NSAutoreleasePool release]
   - _UIApplicationHandleEvent中的#9 0x00300e7f    - PurpleEventCallback中的#10 0x030c4822    - __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION中的#11 0x027c5ff4

   - __CFRunLoopDoSource1中的#12 0x02726807    - __CFRunLoopRun中的#13 0x02723a93    - CFRunLoopRunSpecific中的#14 0x02723350    - CFRunLoopRunInMode中的#15 0x02723271    - GSEventRunModal中的#16 0x030c300c
   - GSEventRun中的#17 0x030c30d1
   - UIApplicationMain中的#18 0x00304af2    - #19 0x0000242c在main.m的主要部分:14

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

3 个答案:

答案 0 :(得分:0)

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

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

这可能对您有用:iPhone - debugging "pointer being freed was not allocated" errors

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

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

答案 1 :(得分:0)

在没有完整源代码的情况下精确定位是一件很难的事,但看起来你正在调用NSString对象上的第二个(并且无效)版本。看看你如何在整个项目中处理字符串。确保它们在您的属性声明中具有'copy'属性,并且您不会不必要地释放已经自动释放的属性。 (即创建[NSString stringWithFormat:])

的那些

答案 2 :(得分:0)

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

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

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