【问题标题】:Declaring an object at class level, problems. iPhone Objective-C在类级别声明对象,问题。 iPhone 目标-C
【发布时间】:2010-12-10 01:38:24
【问题描述】:

iPhone 上的目标 C: 我试图在类级别声明以下对象,这样每次我写东西时我都不必重新连接这个套接字。 (每秒写多次)每当我写一个稳定的实时数据流时,它大约每 2 秒冻结一次。我不知道为什么,但确实如此。

代码:

Socket *socket = [Socket socket];
[socket connectToHostName:@"10.0.2.3" port:1220];

我尝试在实例数据中声明变量,然后在 +initialize 和 viewdidload 中对其进行初始化,均未成功或出现错误。我已经搜索了几个小时试图找到一种方法来解决这个问题,并且在大约 20 种不同的解决方案之后,我没有找到任何可行的方法。顺便说一下,socket 是来自于 Objective-c 的 smallsockets 包中的一个对象。

小插座:http://smallsockets.sourceforge.net/

效果很好,除了每隔几秒就会冻结实时数据。我已将部分代码缩小到这两行。我知道创建然后连接套接字是导致延迟的原因。

任何帮助都非常非常感谢。

谢谢!!

[编辑]

这是我尝试的一些示例代码: 实例声明:

Socket *socket; 

viewDidLoad:

socket = [Socket socket]; //Throws error on compile 

备用视图didload:

Socket *tempSocket = [Socket socket];
socket = tempSocket;
//This compiles fine, however it doesn't work when trying to use it

【问题讨论】:

    标签: iphone objective-c class object instance-variables


    【解决方案1】:

    尝试在类级别声明?

    您的意思是,您希望“socket”成为您为整个类初始化的类范围全局变量,而不是实例?如果是这样,您不能将套接字声明为实例变量。实例变量仅存在于实例(即分配的对象)中。相反,您必须在类之外声明它。全局变量通常在 .m 文件的 #import 行下方声明。

    然后你可以在任何你想要的地方初始化它。我推荐您从 applicationDidFinishLaunching 调用的类方法:

    #import "Socket.h"
    
    Socket *globalSocket = nil;
    
    @implementation Socket
    
    + (void)connectGlobalSocket
    {
        if (!globalSocket)
        {
            globalSocket = [[Socket socket] retain];
            [globalSocket connectToHostName:@"10.0.2.3" port:1220];
        }
    }
    
    ....
    

    【讨论】:

      【解决方案2】:

      如果您的目的地无法到达或其他网络问题导致延迟,会发生什么情况?如果您的远程套接字正在等待某种确认,但您的 iPhone 在它应该发送 ACK 的时间被购买,那该怎么办?如果你没有使用一些类似 select() 的机制,你至少应该在另一个线程中完成所有同步网络的工作。 NSThread 值得一看。

      【讨论】:

      • 如果无法到达目的地,它只会失败。但是,您完全正确。这是网络拥塞。我使用的 wifi 网络涉及使用 mac mini 广播 wifi 网络以连接我的笔记本电脑和 iPhone。当我直接连接笔记本电脑和手机时,它可以完美运行。我宿舍的 mac mini 互联网共享解决方案一直有点慢,但我从没想过它对本地网络连接也会如此糟糕!我仍然想找到一种不必每次都重新创建和连接套接字的方法,但是现在网络拥塞似乎是问题所在。
      【解决方案3】:

      +socket 的代码会很有趣。我的猜测是这是一种方便的方法,即这个套接字的结果是自动释放的。现在我不知道你是否在你的套接字属性中保留这个,但你应该,否则在运行循环完成后,套接字被释放。即你需要一个

      @property (retain) Socket *socket; 
      

      在你的接口文件中。

      【讨论】:

      • 谢谢,我现在就试试。这是+socket的代码。 [CODE] + (Socket*)socket { return [[[Socket alloc] init] autorelease]; } [/CODE]
      • 正如我所料,必须保留来自[Socket socket] 的返回值,否则它不会持续超过 viewDidLoad。
      • 我还担心您上面提到的编译器错误以及为什么它会随着更改而消失。使用便捷方法时,实际上首选第一次尝试。什么是编译器错误? (为 cmets 格式化代码的一种方法是在代码周围使用反单引号。或者在换行时将代码缩进 4 个空格)
      【解决方案4】:

      您可能想要使用AsyncSocket,它提供了带有套接字的异步操作(在 CFSocket 和 CFStream 之上)。

      我在这个StackOverflow answer找到它。

      【讨论】:

        【解决方案5】:

        不要在 +inittailize 中创建套接字,这太早了。

        在 viewDidLoad 中的代码中添加一些调试日志 (NSLog()),并记录套接字以查看它是否已创建。然后在gdb里面打断点,看看是否有效。

        -W

        【讨论】:

        • 在记录它时,我在实例数据中创建了变量“Socket * socket”,并且它工作顺利,直到它尝试以下行:“socket = [Socket socket]”我的另一个想法将它创建为一个单独的对象,然后尝试将新指针保存到实例数据指针的工作原理,但是每当尝试将数据写入它时它就会崩溃。
        • 在原始帖子中添加了两次尝试
        猜你喜欢
        • 1970-01-01
        • 2023-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-04
        • 1970-01-01
        • 2012-11-18
        • 1970-01-01
        相关资源
        最近更新 更多