我创建了一个名为NSOperationDownloadQueue子类。我将所有对象一个一个地添加到NSOperationQueue,即appDelegate.queueDownload

问题是,执行DownloadOperation的对象时,一旦执行downloadDownloadOperation方法,我的DownloadOperation的对象就会从队列中删除。

但是我必须将其保留在内存中,因为当我在downloadFromPath中进行[使用DownloadOperation.m]异步调用并且服务器响应文件数据时,那时DownloadOperation对象被释放并且liveOperationSucceeded从未被调用。

可能是我认为这个问题有点复杂,因此在举报之前请仔细阅读两次!对我来说很重要。感谢您的理解。

    // Adding to queue

    DownloadOperation *operation = [[DownloadOperation alloc] init];

    operation.delegate = self;

    [operation operationWithFileOrFolderID:dictDocument[@"id"] withParentPath:self.strParentPath download:NO withFileName:dictDocument[@"name"] withDictionary:dictDocument];
    [operation download];

    [operation setQueuePriority:NSOperationQueuePriorityVeryHigh];

    [appDelegate.queueDownload addOperation:operation];

DownloadOperation.m(是NSOperation的子类)
@implementation DownloadOperation

-(void)main
{
    [self download];
}

- (void)operationWithFileOrFolderID: (NSString *)strID withParentPath: (NSString *)strParentPath download: (BOOL)isDownload withFileName: (NSString *)strFileName withDictionary: (NSMutableDictionary *)dictInfoLocal
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    self.documentsDirectory = paths[0];

    self.strFileName = strFileName;
    self.strID = strID;
    self.strParentPath = strParentPath;
    self.dictInfo = dictInfoLocal;

    if (self)
    {

    }
}

- (void)download
{
    self.liveClient = [[LiveConnectClient alloc] initWithClientId:CLIENT_ID delegate:self];

    [self.liveClient downloadFromPath:[self.strID stringByAppendingString:@"/content"] delegate:self];

    NSLog(@"DownloadFilesVC : Downloading : %@",self.strFileName);
}

- (void) liveOperationSucceeded:(LiveOperation *)operation
{

}

- (void) liveOperationFailed:(NSError *)error
                   operation:(LiveOperation *)operation
{

}

- (void) liveDownloadOperationProgressed:(LiveOperationProgress *)progress data:(NSData *)receivedData operation:(LiveDownloadOperation *)operation
{

}

@end

最佳答案

您在操作内部有一个异步操作。

操作队列完全按照预期的方式运行,并且在DownloadOperation方法完成后会弹出完成的download。不在乎该操作是否具有回调。

您需要保留DownloadOperation操作的所有权,方法是将其添加到强引用的集合(例如NSArrayNSSet)中,并在LiveConnectClient完成时将其丢弃。您可能希望在DownloadOperation中添加一个BOOL属性来表示。
@property BOOL imReallyReallyFinishedAndCanBeDiscardedOK;
编辑

该API是基于异步/委托的。一种简单的方法是遍历文件夹内容并计算返回响应。收到与请求数量匹配的响应数量后,便知道您已完成。

作为一个非常简化的版本,它不关心递归或错误。

@interface DownloadManager  : NSObject

@property NSArray *fileRefList;
@property NSUInteger count;
@property (strong) void (^completionBlock)();

@end

@implementation DownloadManager

-(void)downloadAllTheFiles {

    self.count = 0;
    for(NSString *strID in self.fileRefList) {

        LiveConnectClient *liveClient = [[LiveConnectClient alloc] initWithClientId:CLIENT_ID delegate:self];
        [liveClient downloadFromPath:[strID stringByAppendingString:@"/content"] delegate:self];

    }

}

- (void) liveOperationSucceeded:(LiveOperation *)operation
{
    self.count++;
    [self haveIFinished];
}

- (void) liveOperationFailed:(NSError *)error
                   operation:(LiveOperation *)operation
{
    self.count++;
    [self haveIFinished];
}

-(void)haveIFinished {

    if (self.count == self.fileRefList.count) {
        if (self.completionBlock) {
            self.completionBlock();
        }
    }

}

让API为您执行队列操作和后台操作。完成后触发任意块。

07-26 09:38