executeInBackgroundWithBlock #132

Closed
dav opened this Issue Jan 16, 2012 · 5 comments

Comments

Projects
None yet
3 participants

dav commented Jan 16, 2012

I wanted to run an arbritary block only after all of the existing blocks sent to [MRCoreDataAction saveDataInBackgroundWithBlock:] had completed. So I added a MRCoreDataAction category:

@interface MRCoreDataAction (Additions)
+ (void) executeInBackgroundWithBlock:(void(^)(void))block;
@end

#import "MRCoreDataAction.h"
#import "MRCoreDataAction+Additions.h"

extern dispatch_queue_t background_save_queue(void);

@implementation MRCoreDataAction (Additions)

+ (void) executeInBackgroundWithBlock:(void(^)(void))block {
  dispatch_async(background_save_queue(), ^{
    block();
  });
}

@end

If you're interested, I could add to base object instead and create a pull request. Or maybe someone thinks it's a dumb idea and wants to tell me why :)

@ghost

ghost commented Jan 16, 2012

What exactly is the problem you're trying to solve? Is it that you have a number of save blocks and want to have a callback when they're complete?
Or, it seems from here that you just want to run some random block on the save queue...that seems dangerous....I think it you can explain the context a little more, we can come up with a more complete solution

Thanks

Saul Mora
Founding Panda
saul@magicalpanda.com

On Jan 16, 2012, at 11:48 AM, Dav Yaginuma wrote:

I wanted to run an arbritary block only after all of the existing blocks sent to [MRCoreDataAction saveDataInBackgroundWithBlock:] had completed. So I added a MRCoreDataAction category:

@interface MRCoreDataAction (Additions)

  • (void) executeInBackgroundWithBlock:(void(^)(void))block;
    @EnD

    #import "MRCoreDataAction.h"
    #import "MRCoreDataAction+Additions.h"

    extern dispatch_queue_t background_save_queue(void);

    @implementation MRCoreDataAction (Additions)

  • (void) executeInBackgroundWithBlock:(void(^)(void))block {
    dispatch_async(background_save_queue(), ^{
    block();
    });
    }

    @EnD

If you're interested, I could add to base object instead and create a pull request. Or maybe someone thinks it's a dumb idea and wants to tell me why :)


Reply to this email directly or view it on GitHub:
#132

dav commented Jan 16, 2012

Yeah, the former.

I get a an array of data objects from a network call. I process this array and end up calling saveDataInBackgroundWithBlock on a bunch of the objects, setting a property on their associated coredata object. The blocks go into the MR background serial queue.

I want to update a UI element according to the result of a query that counts all of those objects with a certain property. I only want to run that UI code and query once, once all the background blocks have finished. The simplest way to do that seemed to be to just reuse the MR bg queue.

@ghost

ghost commented Jan 16, 2012

So, if you noticed one of the other methods has a completion block. Couldn't you use that?
Say:

[MRCoreDataAction performSaveInBackground:^(NSManagedObjectContext *localContext){
for (id item in myArray)
{
//process each item
}
}
completion:^{
// we're done processing, update UI here
}];

I've used a similar block of code to do things similar to what you're saying. While I can see there being a need to submit multiple blocks to the save queue, this will do the same thing, and let you know when it's done. The completion block is called after the call to save is complete, so the store is guaranteed to have the info you need to query, and it's also called on the main queue/thread so you can update UI stuff directly from this block..

Hope this helps,
Saul

Saul Mora
Founding Panda
saul@magicalpanda.com

On Jan 16, 2012, at 1:45 PM, Dav Yaginuma wrote:

Yeah, the former.

I get a an array of data objects from a network call. I process this array and end up calling saveDataInBackgroundWithBlock on a bunch of the objects, setting a property on their associated coredata object. The blocks go into the MR background serial queue.

I want to update a UI element according to the result of a query that counts all of those objects with a certain property. I only want to run that UI code and query once, once all the background blocks have finished. The simplest way to do that seemed to be to just reuse the MR bg queue.


Reply to this email directly or view it on GitHub:
#132 (comment)

dav commented Jan 16, 2012

Fair enough.

Because of other things going on in the loop, I'd have to declare a few vars as __block in order to use your pattern, and I just tend to try to avoid that. Also, conceptually, being able to re-use the existing queue makes sense to me. But I see your point and can understand not wanting to expose the MR-internal background queue.

@ghost

ghost commented Jan 16, 2012

You also don't want to rely on the implementation detail that it's currently a serial queue...
It could become a parallel queue with a few keystrokes :)

__block variables aren't too terrible, and they do get you out of some situations in an easier fashion than others.
That said, you have given me an idea for an API extension that should be to your liking...perhaps I'll have it out on the iOS5 branch in the next few days...we'll see if I can get some time to crank that out..

Saul Mora
Founding Panda
saul@magicalpanda.com

On Jan 16, 2012, at 2:16 PM, Dav Yaginuma wrote:

Fair enough.

Because of other things going on in the loop, I'd have to declare a few vars as __block in order to use your pattern, and I just tend to try to avoid that. Also, conceptually, being able to re-use the existing queue makes sense to me. But I see your point and can understand not wanting to expose the MR-internal background queue.


Reply to this email directly or view it on GitHub:
#132 (comment)

@tonyarnold tonyarnold closed this Dec 14, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment