【问题标题】:Downloading multiple files in iphone app(Objective c)在 iphone 应用程序中下载多个文件(目标 c)
【发布时间】:2009-06-19 02:00:27
【问题描述】:

在我的 iPhone 应用程序中,我想下载 IIS 上的多个文件并进行身份验证。在一个按钮上单击我想开始下载过程。

我知道如何通过身份验证下载文件。

    NSURLRequest* request =
               [NSURLRequest requestWithURL:mMovieURL 
                             cachePolicy:NSURLRequestUseProtocolCachePolicy 
                             timeoutInterval:60.0];
    movieConnection =
            [[NSURLConnection alloc] initWithRequest:request delegate:self ];

我有几个使用上述代码的委托方法。

但是如何同时进行多个下载。

谢谢,

【问题讨论】:

    标签: iphone cocoa cocoa-touch


    【解决方案1】:

    我不熟悉 MultipleDownload,但如果它不能满足您的需求,我认为您有一个对象是许多 NSURLConnections 的委托,而您想要知道如何让他们保持笔直。

    委托方法都返回 NSURLConnection 作为它们的第一个参数。因此,您可以通过测试哪个NSURLConnection 给您回电来跟踪哪些数据去了哪里。一种方法是使用NSDictionary 将连接映射到其NSMutableData 对象。现在的诀窍是你不能让NSURLConnection 成为字典中的键,因为它不符合NSCopying(你不希望它这样做)。解决此问题的一种方法是使用连接地址,例如:

    NSString *key = [NSString stringWithFormat:@"%p", connection];
    

    这将为任何对象返回一个唯一键(其地址的十六进制表示)。有些人为此使用description,但我不喜欢这样,因为它不是一个定义明确的接口。没有保证它是独一无二的。在我经常这样做的系统中,我在一个名为-uniqueIdentifier 的方法中实现了上述-stringWithFormat:,并将其设为NSObject 上的一个类别,因此可以在字典中跟踪任何内容。

    我经常发现创建一个小的包装对象更容易,这样每个对象都可以控制自己的NSURLConnection,就像我确信MultipleDownload 正在做的那样,但这种技术在各种情况下仍然有用,无论您是管理多个 tableview,还是其他任何有委托的东西。

    编辑:如 Peter 所述,将我上面的 %x 替换为 %p。他是对的,我的想法不正确。仔细检查我的代码,我实际上一直在使用 %p,之前遇到过这个错误......

    【讨论】:

    • 对指针使用 %p,而不是 %x。 %x 是无符号整数,并且不能保证指针的大小与 int 相同(实际上,在 64 位版本的 Mac OS X 上,它不是相同的大小)。跨度>
    • 您现在可以使用NSMapTable 将任意对象用作键。来自文档:“它的键或值可以在输入时复制,或者可以使用指针标识进行相等和散列。”这消除了本说明中对 key 对象的需求。
    【解决方案2】:

    当我想同时下载 10 个 XML 文件时,我曾经这样做过(这比将它们一个接一个地排队下载要快得多)。我使用了这里找到的库:

    http://github.com/leonho/iphone-libs/tree/master

    它们很容易实现,首页上有一些示例代码可以帮助您入门。

    self.urls = [NSMutableArray arrayWithObjects:
        @"http://maps.google.com/maps/geo?output=json&q=Lai+Chi+Kok,Hong+Kong",
        @"http://maps.google.com/maps/geo?output=json&q=Central,Hong+Kong",
        @"http://maps.google.com/maps/geo?output=json&q=Wan+Chai,Hong+Kong",
        nil];
    
    self.downloads = [[MultipleDownload alloc] initWithUrls: urls];
    self.downloads.delegate = self;
    

    祝你好运。

    【讨论】:

      【解决方案3】:

      我认为最简单的方法是使用 NSOperation - 和 NSOperationQueue。

      这意味着您可以指定每个操作是顺序发生还是并行发生。您甚至可以限制并行操作的数量 - 以便一次最多运行 5 个(比如说),然后其他操作在后面排队。

      这确实是让操作系统处理多个活动的好方法 - 并且与 iPhone 操作系统的延迟加载类型理念配合得很好。

      然后,您可以让每个操作在完成时进行回调 - 甚至在主线程上进行进度回调。

      我已将我的代码更改为现在以这种方式工作,并发现它更加健壮且用户友好。

      【讨论】:

      • 问题是 nsoperation 无法处理异步下载,异步下载将在稍后完成,而不是立即完成。
      • 我不认为这是正确的 - 我认为这确实是 NSOperation 的全部意义
      【解决方案4】:

      我不熟悉 MultipleDownload,但以防万一 不符合您的需求,我的问题 假设你有一个单身 作为许多委托的对象 NSURLConnections,你想知道 如何保持笔直。

      委托方法都返回 NSURLConnection 本身作为他们的第一个 范围。所以你可以跟踪 通过测试哪些数据去哪里 NSURLConnection 正在给你回电。 一种方法是使用 映射连接的 NSDictionary 到它的 NSMutableData 对象。现在 诀窍是你不能做一个 NSURLConnection 是一个关键 字典,因为它不符合 到 NSCopying (你不会想要它 到)。解决此问题的一种方法是 使用连接的地址,例如 如:

      NSString *key = [NSString stringWithFormat:@"%p", 连接];

      更好的方法是将NSValuevalueWithNonretainedObject 构造函数一起使用。这样,您可以在必要时从 NSDictionary 访问密钥对象。

      【讨论】:

        【解决方案5】:

        NSURLConnection 是异步的,init 立即退出。多次运行即可。

        NSArray *connections = [[NSArray alloc] initWithObjects:
          [[NSURLConnection alloc] initWithRequest:request1 delegate:self ],
          [[NSURLConnection alloc] initWithRequest:request2 delegate:self ],
          [[NSURLConnection alloc] initWithRequest:request3 delegate:self ],
          [[NSURLConnection alloc] initWithRequest:request4 delegate:self ],
          nil];
        

        【讨论】:

        • 我不知道。如果其中一个文件发生错误怎么办。如果其中一个比其他人花费更长的时间怎么办。当它们都完成后,你如何跟踪它们?
        猜你喜欢
        • 2010-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多