0

我正在使用 Nico Kreipke 的 FTPManager(单击此处转到 GiHub)从 FTP 地址下载一些数据。

如果代码在用户第一次交互之前运行,那么它通常会失败(大约十分之九)。

当它失败时,将写入以下消息(0x_ 实际上是有效地址):

request (0x_) other than the current request(0x0) signalled it was complete on connection 0x_

该消息不是由我的代码或 FTPManager 编写的,而是由 Apple 编写的。在它的 GitHub 上,我发现了一些有相同错误的错误,但它的来源可能与我的相同。(那个人没有使用 ARC。)

如果我尝试使用po命令打印这些地址的对象,控制台会写道没有可用的描述。

此外,内存不断增加,直到应用程序收到内存警告,并且在操作系统终止它后不久。

通过在出现该消息时暂停应用程序,我可以看到主线程处于运行循环中。

CFRunLoopRun();

编码

self.ftpManager = [[FTPManager alloc] init];
[self downloadFTPFiles:@"192.168.2.1/sda1/1668"];

ftpManager是一个强有力的参考。

downloadFTPFiles:方法:

- (void) downloadFTPFiles:(NSString*) basePath
{
    NSLog(@"Reading contents of path: %@", basePath);

    FMServer* server = [FMServer serverWithDestination: basePath username:@"test" password:@"test"];

    NSArray* serverData = [self.ftpManager contentsOfServer:server];

    NSLog(@"Number of items: %d", serverData.count);

    for(int i=0; i < serverData.count; i++)
    {
        NSDictionary * sDataI = serverData[i];
        NSString* name = [sDataI objectForKey:(id)kCFFTPResourceName];
        NSNumber* type = [sDataI objectForKey:(id)kCFFTPResourceType];

        if([type intValue] == 4)
        {
            NSLog(@"%@ is Folder", name);
            NSString * nextDestination = [basePath stringByAppendingPathComponent: name];
            [self downloadFTPFiles:nextDestination];
        }
        else
        {
            NSLog(@"%@ is File", name);
            [self.ftpManager downloadFile:name toDirectory:[NSURL fileURLWithPath:NSHomeDirectory()] fromServer:server];
        }
    }
}

我做了什么

我尝试在几个地方运行该代码:

  • 应用程序委托的application:didFinishLaunchingWithOptions:;

  • 在应用程序启动后加载的视图控制器和稍后呈现的视图控制器的,viewDidLoadviewWillAppear:viewDidAppear:

  • 通过按钮事件触发的操作。

当代理或加载了应用程序的视图控制器执行时,数据的下载始终执行良好(有一个例外)。但是在用户第一次与应用程序交互后运行时,它很可能会因上述错误而失败。

在用户第一次交互之前加载的视图控制器的例外是当调用在viewWillAppear:orviewDidAppear:方法中时。当它被第二次调用时(例如,标签栏控制器的标签),它也很可能会失败。

问题

有没有人知道可能发生的事情,或者我做错了什么?或者任何替代解决方案,也许?

任何解决此问题的帮助都将受到欢迎。

谢谢,
蒂亚戈

4

1 回答 1

2

我最终在一个块downloadFile:toDirectory:fromServer:内发送消息。dispatch_async我还为每个下载的文件创建了一个 FTPManage。

它起作用了,但我不知道为什么。

我把这个答案留给遇到这个问题的人。

如果有人可以让我知道为什么这种技术有效,请在下面发表评论,以便我更新答案。

这是我下载每个文件的新方法:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    FTPManager *manager = [[FTPManager alloc] init];
    [manager downloadFile:name toDirectory:[NSURL fileURLWithPath:path] fromServer:server];
});

同样,如果您知道为什么会这样,请告诉我。

谢谢。

完整方法

- (void) downloadFTPFiles:(NSString*) basePath
{
    NSLog(@"Reading contents of path: %@", basePath);

    FMServer *server = [FMServer serverWithDestination:basePath username:@"test" password:@"test"];

    NSArray *serverData = [self.ftpManager contentsOfServer:server];

    NSLog(@"Number of items: %d", serverData.count);

    for(int i=0; i < serverData.count; i++)
    {
        NSDictionary *sDataI = serverData[i];
        NSString *name = [sDataI objectForKey:(id)kCFFTPResourceName];
        NSNumber *type = [sDataI objectForKey:(id)kCFFTPResourceType];

        if([type intValue] == 4)
        {
            NSLog(@"%@ is Folder", name);
            NSString *nextDestination = [basePath stringByAppendingPathComponent:name];
            [self downloadFTPFiles:nextDestination];
        }
        else
        {
            NSLog(@"%@ is File", name);
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                FTPManager *manager = [[FTPManager alloc] init];
                [manager downloadFile:name toDirectory:[NSURL fileURLWithPath:path] fromServer:server];
            });
        }
    }
}
于 2013-10-14T18:00:09.893 回答