【问题标题】:2nd use of NSURLConnection causes SIGABRT iPhone第二次使用 NSURLConnection 导致 SIGABRT iPhone
【发布时间】:2012-05-19 18:03:42
【问题描述】:

我搜索了很多关于 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;
}

所以这一切都很好。问题是稍后我尝试发布一个请求(来自不同的类中),不久之后,应用程序在一个单独的线程上的程序集负载中使用 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 杀死
-#1 0x90d7e124 in kill$UNIX2003
-#2 0x90e108e5 加注
-#3 0x90e2699c 中止
-#4 0x90d23d35 免费
-#5 0x026fc081 in __CFStringDeallocate
-#6 0x026fbccb 在 _CFRelease
-#7 0x02720c9d 在 _CFAutoreleasePoolPop
-#8 0x0004fe67 in -[NSAutoreleasePool 发布]
-#9 0x00300e7f in _UIApplicationHandleEvent
-#10 0x030c4822 在 PurpleEventCallback
-#11 0x027c5ff4 在 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION

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

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

【问题讨论】:

  • 嗯,来自控制台的更多信息:prjname(1482,0xa00f54e0) malloc: *** 对象 0x818c0b0 的错误:未分配指针被释放 *** 在 malloc_error_break 中设置断点以调试收到的程序信号:“SIGABRT”。注意:我自己在这个项目中没有使用任何c或c++代码,都是客观c所以这必须是sdk代码或其他东西创建的对象。

标签: cocoa nsurlconnection sigabrt


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2011-08-11
        • 2022-01-05
        • 1970-01-01
        • 1970-01-01
        • 2014-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多