【问题标题】:Multithreading and JSON/NSURLConnection on the iPhoneiPhone 上的多线程和 JSON/NSURLConnection
【发布时间】:2011-06-27 09:44:24
【问题描述】:

我正在编写一个使用多线程和缓存的应用程序。与 Apple 的 TopSongs 示例代码非常相似。启动时,我需要在 JSON 提要中获取对象的值。

现在我担心这样做会破坏应用程序的工作流程,如果我使用 NSURLConnection 会阻塞线程或其他东西。我可以不使用 NSURLConnection 的委托方法只下载那个 JSON 提要(它只有一个对象)吗?如果我在我的委托文件中实现委托方法,那么应用程序将完成 applicationDidFinishLaunching:application 方法,然后转到

connection:didReceiveResponse:
connection:didReceiveData:
connection:didFailWithError:
connectionDidFinishLoading:

我怎样才能避免这种情况?我需要在 applicationDidFinishLaunching:application 的开头获取时间戳(存储在该 JSON 文件中),因为该方法的其余部分取决于该时间戳。

谢谢,

【问题讨论】:

    标签: iphone objective-c multithreading xcode json


    【解决方案1】:

    有两种方法可以实现:

    使用 NSURLConnection 的 sendSynchronousRequest,但这会阻塞直到收到响应

    + (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
    

    或(更好的选择

    将依赖 JSON 的代码移至单独的方法。正常使用 NSURLConnection 的异步 + 委托方法,但在您的 applicationDidFinishLaunching 方法中显示 some sort of HUD 以通知用户正在发生的事情,然后在 connection:didReceiveResponse 方法中或connectionDidFinishLoading 方法调用依赖于 JSON 的新方法(现在将具有 JSON)并关闭 HUD。

    【讨论】:

    • 感谢您的全面回复。在我将此标记为正确答案之前,请进行一些澄清:在第一个解决方案中,这将阻止所有线程,直到检索到提要?这是推荐/有效的还是取决于情况?
    • @Nayefc 这个方法在主线程上被调用,所以阻塞那个并且只有那个。然而,所有的 UI 都是在主线程上绘制的,所以沿着这条路线走会让你的应用在启动时看起来没有响应,因为所有交互都会被阻止,直到方法返回响应。 IMO 的第二个选项将是首选,它将为最终用户提供更好的用户体验。
    • 我实际上是从网站的空白页面上获取一个字符串。在这种情况下会注意到 UI 延迟吗?
    • @Nayefc 它与有效负载无关,更多的是整个请求往返(例如,如果我通过 Edge 而不是 3G 或 WiFi 连接,延迟会更大) 但你最好的办法是试一试。另一方面,如果请求是快速,那么加载和显示 HUD 只是为了立即关闭它也可能会呈现糟糕的用户体验。我很确定您的 default.png 会一直显示到 applicationDidFinishLaunching 返回,如果是这种情况,那么无论如何这都是微不足道的。
    【解决方案2】:

    当您说“应用程序将完成 applicationDidFinishLaunching 然后转到

    时,我不确定我是否理解您的意思

    connection:didReceiveResponse: connection:didReceiveData: connection:didFailWithError: connectionDidFinishLoading:"

    你能再解释一下吗?

    关于方法的要点取决于您需要从 JSON 文件中获取的时间戳,我建议您需要审查您的应用程序设计以及您在方法中所做的事情。

    【讨论】:

    • 我的应用使用核心数据。启动时,它从 JSON 提要下载数据并使用 Core Data 存储它们。 JSON 提要不会经常更改,因此我有一个 JSON 提要,它将上次更新的时间戳存储在在线数据库上。它也存储在 NSUserDefaults 中。现在它会检查提要中的最后一个更新时间戳是否比存储在 NSUserDefaults 中的更新。如果是这样,它会重新下载数据。否则,它不会。
    • 我的意思是,在转到 connection:didReceiveResponse 并下载 JSON 提要之前,将调用方法 applicationDidFinishLaunching。事实上,我需要在 applicationDidFinishLaunching 完成之前下载我的 JSON 提要。
    • 我会说你需要重新审视你的应用程序设计。在不知道您在 applicationDidFinishLaunching 中做什么的情况下,很难提出任何具体的建议,但没有理由在应用程序完成下载文件后无法触发更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多