【问题标题】:Application Freezing when calling CocoaAsyncMethod scheduleDequeueRead调用 CocoaAsyncMethod scheduleDequeueRead 时应用程序冻结
【发布时间】:2012-06-12 19:18:31
【问题描述】:

我正在使用 CocoaAsyncSocket 库来创建 TCP 套接字连接。我遇到的问题是在调用了几个库方法后,我得到了一个错误。

appDelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{   
    socket = [[AsyncSocket alloc] initWithDelegate:self];
    NSError *error = nil;
    if (![socket connectToHost:@"199.5.83.63" onPort:11005 error:&error]) 
    {
        NSLog(@"Error connecting: %@", error);
    }

    [socket readDataWithTimeout:10 tag:1];

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.viewController = [[[tekMatrixViewController alloc] initWithNibName:@"tekMatrixViewController" bundle:nil] autorelease];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

这是我在 CocoaAsyncSocket 库中的方法:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSData *strData = [data subdataWithRange:NSMakeRange(0, [data length])];
    NSString *msg = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
    NSLog(@"RX length: %d", [data length]);
    if(msg)
    {
        NSLog(@"RX:%@",msg);
    }
    else 
    {
        NSLog(@"Fail");
    }    
}

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
    NSLog(@"error - disconnecting");
    //start reconnecting procedure here...
}

- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
    NSLog(@"disconnected");
}

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"connected");
}

当我在模拟器中运行我的应用程序时,我的输出日志是这样输出的:

2012-06-08 13:17:30.808 tekMatrix[2793:f803] connected
2012-06-08 13:17:30.815 tekMatrix[2793:f803] RX length: 8
2012-06-08 13:17:30.816 tekMatrix[2793:f803] Fail

之后,我在此方法中的 AsyncSocket.m 文件(库的一部分)中出现错误:

- (void)scheduleDequeueRead
{
    if((theFlags & kDequeueReadScheduled) == 0)
    {
        theFlags |= kDequeueReadScheduled;
        [self performSelector:@selector(maybeDequeueRead) withObject:nil afterDelay:0 inModes:theRunLoopModes];
    }
}

具体是在线出错:

[self performSelector:@selector(maybeDequeueRead) withObject:nil afterDelay:0 inModes:theRunLoopModes];

例外情况是:线程 1:BAD_EXC_ACCESS(代码 1=0,地址=0xd0688b8a)

之后,应用程序在模拟器中完全冻结。如果有人能就这导致应用程序冻结的原因提供一些见解,我将不胜感激。

这是我正在使用的库:CocoaAsyncSocket

编辑:

启用 Zombie Objects 并在模拟器中运行应用程序后,输出中会显示以下内容:

2012-06-08 14:53:15.416 tekMatrix[3217:f803] *** -[__NSArrayI count]: message sent to deallocated instance 0x6d10a70

我将不得不对此进行一些挖掘并弄清楚发生了什么。

编辑 2:

使用仪器稍微挖掘后,我发现了以下内容:

An Objective-C message was sent to a deallocated object (zombie) at address: 0x6b8bb10.

编辑 3:

现在错误显示为:

线程 1:EXC_BREAKPOINT(code=EXC_I386_BPT, subcode=0x0)

这是仪器的屏幕截图。不过,我并没有真正关注如何解释这一点。看起来我正在向已释放的对象发送消息。这是真的?如果是这样,我该如何确定发生这种情况的位置?

如果图片很难看,这里是直接链接:Instruments Screenshot

【问题讨论】:

  • 你能展示代码吗,你在哪里创建了 AsyncSocket 对象?连同属性,如果它被写入一个。
  • AsyncObject 位于 didFinishLaunchingWithOptions 方法的顶部。当我清理注释掉的行时,我无意中遗漏了那行代码。
  • 我不知道这是否有帮助,但如果我删除“[socket readDataWithTimeout:10 tag:1];”行那么应用程序不会冻结或产生错误。它只连接主机,不读取任何数据。
  • 看起来不像。我整理的大部分代码都是在教程和 SO 用户的帮助之间共同整理的。为什么我需要使用属性套接字?
  • 你知道什么是属性吗?

标签: iphone objective-c ios cocoaasyncsocket


【解决方案1】:

您正在尝试访问一个不再存在的对象。可能您保留不足/过度释放它。

有关查找此类对象的工具,请参阅此答案:How do I set up NSZombieEnabled in Xcode 4?

【讨论】:

  • 赞成,因为答案至少允许原始提问者改进问题。
  • @vikingosegundo 我很抱歉。我还在学习 SO 的功能。投票赞成:)
【解决方案2】:

我知道这是事后诸葛亮,但我也遇到了同样的问题。解决方案是将 ARC 标志添加到 AsyncSocket.m,-fobjc-arc

:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    相关资源
    最近更新 更多