您的位置:首页 > 产品设计 > UI/UE

iOS - How to know when NSOperationQueue finish processing a few operations?

2014-11-02 18:02 471 查看
转自:http://stackoverflow.com/questions/9998532/ios-how-to-know-when-nsoperationqueue-finish-processing-a-few-operations

6down
votefavorite

10

I need in my application to download directories and their content. So I decided to implement a NSOperationQueue and I subclassed NSOperation to implement NSURLRequest etc...

The problem is I add all the operations at once and I can't figure out when all the files for one directory are downloaded in order to update the UI and enable this specific directory.

Now I have to wait that all the files from all the directories are downloaded in order to update the UI.

I already implemented key-value observing for the operationCount of the NSOperationQueue and the isFinished of the NSOperation but I don't know when a directory has all the files in it !

Do you have any idea ?

Thanks a lot

iphone ios ipad download nsoperation
share|improve
this question
asked Apr 3 '12 at 17:42





Dabrut

472720

It is more convenient to use dispatch_group_async. See this link [link][1] [1]:stackoverflow.com/questions/9632235/… – Igor
Fedorchuk Mar
18 at 8:43
add
a comment


4 Answers

activeoldestvotes

up
vote26down
voteaccepted
Add a "Done"
NSOperation
which
has all other
NSOperations
for
one directory as dependency.

Something like this:
NSInvocationOperation *doneOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(done:) object:nil];

NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
[queue addOperation:op1];
[doneOp addDependency:op1];

NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
[queue addOperation:op2];
[doneOp addDependency:op2];

NSInvocationOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
[queue addOperation:op3];
[doneOp addDependency:op3];

[queue addOperation:doneOp];


doneOp
will
only run after
op1
,
op2
and
op3
have
finished executing.

share|improve
this answer
edited Apr
5 '12 at 5:24





Costique

16.4k24562

answered Apr 3 '12 at 20:02




Matthias Bauch

54.8k5122166

I forgot to mention that my operations are concurrent. Is your example still ok ? – Dabrut Apr
3 '12 at 21:37
Of course, that's the whole point of dependencies. In a non-concurrent operation queue you would just add your operations in the correct
order to achieve the same. But an operation will not run until all its dependencies have finished executing. – Matthias
Bauch Apr
4 '12 at 10:08
Kudos to you. That's exactly what I was looking for ! – Dabrut Apr
4 '12 at 20:14
Quite an elegant solution! – Costique Apr
5 '12 at 5:25
Many thanks for your answer help me – wod Jan
21 '13 at 7:12
add
a comment





up
vote4down
vote
[opQueue operationCount]


Hope this helps

share|improve
this answer
answered Feb 5 '13 at 11:39




Radix

2,0581743

add
a comment
up
vote0down
vote
One approach would be to create some sort of Directory class with a properties such as loadedCount (initially 0) and fileCount (initialized to however many files are in the directory) and create a dictionary mapping each NSOperation to the appropriate Directory
before adding the operation to the queue. Inside your callback for isFinished, you could pull the Directory object for the given NSOperation out of the dictionary and increment the directory.loadedCount by 1. If your directory.loadedCount == directory.fileCount,
trigger an update to the UI.

share|improve
this answer
answered Apr 3 '12 at 18:56





tronbabylove

80148

That was my first idea. But I was wondering if that was the correct way to do it or if there was a better way to do it. – Dabrut Apr
3 '12 at 19:08
add
a comment
up
vote0down
vote
You can refactor your code to avoid enqueuing all requests at once. Enqueue only requests for a single directory at a time. When
operationCount
reaches
zero, you can be sure that all the requests either completed or failed, update the UI and enqueue the requests for the next directory. Proceed until the array of directories is empty.

The advantages are:

relative simplicity

you don't have to query the file system only to figure out what has been downloaded

if need be, you can re-enqueue failed requests without changing other logic.

share|improve
this answer
answered Apr 3 '12 at 19:56





Costique

16.4k24562

add
a comment
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: