I would like to pass in different blocks into a method. The method would subsequently use the passed in block as parameter to dispatch_async.
I have my block declared like this:
typedef int (^ComputationBlock)(int);
The class method that accepts the block is implemented as:
- (void)doSomething:(int)limit withBlock:(ComputationBlock)block;
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// typical in-lined block for dispatch_async:
dispatch_async(queue, ^{
// do some work here
});
// I want to pass in the block as the 2nd parameter to dispatch_async
// but the compiler will warn me of a type mismatch unless I cast
// the block like:
dispatch_async(queue, (dispatch_block_t)block);
}
#end
Is it okay to typecast the 'block' parameter as dispatch_block_t?
No, that's not cool to do -- the block passed to dispatch_async needs to take no parameters and return nothing. Casting your ComputationBlock to that would be a Bad Idea (it's not nice to fool mother nature).
Simply wrap your block that you want to call inside one of the right type:
dispatch_async(queue, ^{ block(0); } );
(note that you also need to supply a parameter to your ComputationBlock when you invoke it.)
It may compile, but it won't work. dispatch_block_t blocks must not take any arguments and must not have a return value.
Pass value using __block
__block int backValue;
it can modify in block
Related
I found conception of Delegates pretty hard for me. I really do not understand why I can't simply pass one function to another and need to wrap it to Delegate. I read in docs that there is some cases when I do not know it's name and Delegate is only way to call it.
But now I have trouble in understanding conception of callbacks. I tried to find more information, but I can't understand is it's simply call of other function or what is it.
Could you show examples of D callbacks and explain where they can be helpful?
import vibe.d;
shared static this()
{
auto settings = new HTTPServerSettings;
settings.port = 8080;
listenHTTP(settings, &handleRequest);
}
void handleRequest(HTTPServerRequest req,
HTTPServerResponse res)
{
if (req.path == "/")
res.writeBody("Hello, World!", "text/plain");
}
&handleRequest is it callback? How it's work and at what moment it's start?
So within memory a function is just a pile of bytes. Like an array, you can take a pointer to it. This is a function pointer. It has a type of RETT function(ARGST) in D. Where RETT is the return type and ARGST are the argument types. Of course attributes can be applied like any function declaration.
Now delegates are a function pointer with a context pointer. A context pointer can be anything from a single integer (argument), call frame (function inside of another) or lastly a class/struct.
A delegate is very similar to a function pointer type at RETT delegate(ARGST). They are not interchangeable, but you can turn a function pointer into a delegate pointer pretty easily.
The concept of a callback is to say, hey I know you will know about X so when that happens please tell me about X by calling this function/delegate.
To answer your question about &handleRequest, yes it is a callback.
You can pass functions to other functions to later be called.
void test(){}
void receiver(void function() fn){
// call it like a normal function with 'fn()'
// or pass it around, save it, or ignore it
}
// main
receiver(&test); // 'test' will be available as 'fn' in 'receiver'
You need to prepend the function name as argument with & to clarify you want to pass a function pointer. If you don't do that, it will instead call that function due to UFCS (calling without braces). It is not a delegate yet.
The function that receives your callable may do whatever it wants with it. A common example is in your question, a web service callback. First you tell the framework what should be done in case a request is received (by defining actions in a function and making that function available for the framework), and in your example enter a loop with listenHTTP which calls your code when it receives a request. If you want to read more on this topic: https://en.wikipedia.org/wiki/Event_(computing)#Event_handler
Delegates are function pointers with context information attached. Say you want to add handlers that act on other elements available in the current context. Like a button that turns an indicator red. Example:
class BuildGui {
Indicator indicator;
Button button;
this(){
... init
button.clickHandler({ // curly braces: implicit delegate in this case
indicator.color = "red"; // notice access of BuildGui member
});
button.clickHandler(&otherClickHandler); // methods of instances can be delegates too
}
void otherClickHandler(){
writeln("other click handler");
}
}
In this imaginary Button class all click handlers are saved to a list and called when it is clicked.
There were several questions in the OP. I am going to try to answer the following two:
Q: Could you show examples of D callbacks and explain where they can be helpful?
A: They are commonly used in all languages that support delegates (C# for an example) as event handlers. - You give a delegate to be called whenever an event is triggered. Languages that do not support delegates use either classes, or callback functions for this purpose. Example how to use callbacks in C++ using the FLTK 2.0 library: http://www.fltk.org/doc-2.0/html/group__example2.html. Delegates are perfect for this as they can directly access the context. When you use callbacks for this purpose you have to pass along all the objects you want to modify in the callback... Check the mentioned FLTK link as an example - there we have to pass a pointer to the fltk::Window object to the window_callback function in order to manipulate it. (The reason why FLTK does this is that back FLTK was born C++ did not have lambdas, otherwise they would use them instead of callbacks)
Example D use: http://dlang.org/phobos/std_signals.html
Q: Why I can't simply pass one function to another and need to wrap it to Delegate?
A: You do not have to wrap to delegates - it depends what you want to accomplish... Sometimes passing callbacks will just work for you. You can't access context in which you may want to call the callback, but delegates can. You can, however pass the context along (and that is what some C/C++ libraries do).
I think what you are asking is explained in the D language reference
Quote 1:
A function pointer can point to a static nested function
Quote 2:
A delegate can be set to a non-static nested function
Take a look at the last example in that section and notice how a delegate can be a method:
struct Foo
{
int a = 7;
int bar() { return a; }
}
int foo(int delegate() dg)
{
return dg() + 1;
}
void test()
{
int x = 27;
int abc() { return x; }
Foo f;
int i;
i = foo(&abc); // i is set to 28
i = foo(&f.bar); // i is set to 8
}
There are already excellent answers. I just want to try to make simple summary.
Simply: delegate allows you to use methods as callbacks.
In C, you do the same by explicitly passing the object (many times named context) as void* and cast it to (hopefully) right type:
void callback(void *context, ...) {
/* Do operations with context, which is usually a struct */
doSomething((struct DATA*)context, ...);
doSomethingElse((struct DATA*)context, ...);
}
In C++, you do the same when wanting to use method as callback. You make a function taking the object pointer explicitly as void*, cast it to (hopefully) right type, and call method:
void callback(void* object, ...) {
((MyObject*)object)->method(...);
}
Delegate makes this all implicitly.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Right now, I got a GET request, after it's finished, I got the json back, and then I want to use the id from the json to execute another fetch request. It's like a nested fetch request right after another. For example:
+ (void)searchPhotoWithTags:(NSArray *)tags page:(NSInteger)page perPage:(NSInteger)perPage completionBlock:(void (^)(NSArray *, NSError *))block
{
NSDictionary *dict = #{#"method": #"search", #"api_key": kAppKey, #"tags": [tags componentsJoinedByString:#","], #"per_page": [NSString stringWithFormat:#"%d", perPage], #"page": [NSString stringWithFormat:#"%d", page], #"format": #"json"};
[[LDHttpClient sharedClient] getPath:#"" parameters:dict success:^(AFHTTPRequestOperation *operation, id responseObject) {
[[responseObject valueForKeyPath:#"photos.photo"] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
Photo *photo = [[Photo alloc] initWithPhotoId:[NSNumber numberWithInt:[obj[#"id"] integerValue]] andSecret:obj[#"secret"]];
//down below, I want to use photo.photoId to execute another request but the data is not completed. what's the better way to do this?
[PhotoSize getPhotoSizesWithPhotoId:photo.photoId completionBlock:^(NSArray *photoSizes, NSError *error) {
[photos addObject:#{#"photo": photo, #"sizes": photoSizes}];
}];
}];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
}];
}
If I understood your question correctly, I think what you're witnessing is a problem of asynchronous.
You are trying to loop through your photos dictionary, getting the photo size of each photo by means of sending another GET request which is an asynchronous operation. However, because of that, the next iteration of your loop already executes before your previous asynchronous operation has finished.
In this case, what you can do is use recursion to help you "iterate" or "loop" through your photos dictionary.
Requirements
For the below code to work, you'll need to create 2 properties
A property for storing your "photos" NSDictionary (e.g. NSDictionary *photosDict) in yourClass.h file
Another property for storing the enumerator of "photos" NSDictionary, which will be of type NSEnumerator, maybe call it "photosEnum"
Cleaning up your code a bit
In your original method, store the photos dictionary and from that, store the photosEnum enumerator too:
+ (void)searchPhotoWithTags:(NSArray *)tags page:(NSInteger)page perPage:(NSInteger)perPage completionBlock:(void (^)(NSArray *, NSError *))block
{
NSDictionary *dict = #{#"method": #"search", #"api_key": kAppKey, #"tags": [tags componentsJoinedByString:#","], #"per_page": [NSString stringWithFormat:#"%d", perPage], #"page": [NSString stringWithFormat:#"%d", page], #"format": #"json"};
[[LDHttpClient sharedClient] getPath:#"" parameters:dict success:^(AFHTTPRequestOperation *operation, id responseObject) {
// I assume you have a property of type NSDictionary created called "photos"
self.photosDict = [responseObject valueForKeyPath:#"photos"];
// Also create a property for the enumerator of type NSEnumerator
self.photosEnum = [self.photosDict objectEnumerator];
// ----------------------------------------------------------
// First call of our recursion method
//
// This will start our "looping" of our photos enumerator
// -----------------------------------------------------------
[self processPhotoDictionary];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failed to get photos, error: %#", [error localizedDescription]);
}];
}
And finally, our recursion method does the processing of the photoSizes:
-(void)processPhotoDictionary
{
// ------------------------------------------------------
// Because self.photosEnum is a property of our class
// it remembers where it is "up to" in the "looping"
// ------------------------------------------------------
NSDictionary *photo = [self.photosEnum nextObject];
if(photo != nil)
{
Photo *photoObj = [[Photo alloc] initWithPhotoId:[NSNumber numberWithInt:[[photo valueForKey:#"id"] integerValue]]
andSecret:[photo valueForKey:#"secret"]];
[PhotoSize getPhotoSizesWithPhotoId:photoObj.photoId completionBlock:^(NSArray *photoSizes, NSError *error) {
[photos addObject:#{#"photo": photoObj, #"sizes": photoSizes}];
// ------------------------------------------------------
// Here we're using recursion to iterate through our
// enumerator due to asynchronous nature instead of the
// while loop.
// ------------------------------------------------------
[self processPhotoDictionary];
}];
}
}
Hope that helps.
In addition to the excellent answer of #Zhang, I would like to describe the common problem the OP is facing and how a "general solution" to this common problem may look like.
The common objective is:
Fetch a list of items from a server. Each item contains a URL which points to some other resource (an image for example).
When the list has been received, for each item in the list, fetch the resource (the image) given by the URL.
When implementing this in synchronous style the solution is obvious, and actually quite easy. However, when employing asynchronous style - which is the preferred way when doing networking - a workable solution becomes surprisingly complex, unless you know how to solve such problems ;)
The interesting part here is #2. Part #1 can be simply accomplished via an asynchronous call and a completion function where the completion function invokes part #2.
In order to make the things more easy to understand I will make a few simplifications and a few prerequisites:
In part #1 we obtain a list of elements, say an NSArray object containing our elements. Each element has a property, which is a URL to another resource.
Now, we can easily make the assumption that we already have an array of elements representing the N input values which shall be asynchronously processed in a loop - one after the other. Let us name that array "Source Array".
We will deal with asynchronous methods/functions. One way to have the method/function signal that it is finished with processing something asynchronously is a completion handler (a block).
The common signature for all completion handlers will be defined as follows:
typedef void (^completion_t)(id result);
Note: result shall represent the eventual result of the asynchronous function or method. It may be the kind of thing we expect (an image for example), or it may indicate an error, for example through passing and NSError object.
In oder to implement our part #2, we need an asynchronous method/function which takes an input (one element from the Input Array) and produces an output. This corresponds to your "fetch image resource" task. Later we need to apply this method/function for each element of the "Input Array" we got in part #1.
The generic function, a "transform function", will have this signature:
void transform(id input, completion_t completion);
The corresponding method will have this signature:
-(void) transformWithInput:(id)input
completion:(completion_t)completionHandler;
We can define a typedef for the function as below:
typedef void (^transform_t)(id input, completion_t completion);
Notice, that the result of the transform function or method will be passed through the completion handler's parameter. An synchronous function would just have a return value and return the result.
Note: the name "transform" is just a generic name. You can wrap your network request in a method and get such kind of "transform" function. In the OP's example, the URL would be the input parameter and the completion handler's result parameter would be the image fetched from the server (or an error).
Note: this and the following simplifications are just there to make the explanation of the asynchronous pattern easier to understand. In practice an asynchronous function or method may take other input parameters, and the completion handler may also have other parameters.
Now, the more "tricky" part:
Implementing A Loop In Asynchronous Style
Well, this is a bit "different" than in synchronous programming style.
Purposefully, we define some kind of forEach function or method doing this iteration. That function or method is itself asynchronous! And we know now that any asynchronous function or method will have a completion handler.
So, in case of a function we can declare our "forEach" function as follows:
`void transform_each(NSArray* inArray, transform_t task, completion_t completion);`
transform_each sequentially applies an asynchronous transform function task to each object in the input array inArray. When finished processing all inputs, it invokes the completion handler completion.
The completion handler's result parameter is an array containing the result of each transform function in the same order as the corresponding input.
Note: "sequentially" here means, that the inputs are processed one after the other. A variant of that pattern may process the inputs in parallel.
The parameter inArray is our "Input Array" gathered from step #1.
Parameter task is our asynchronous transform function, which can be virtually anything which takes an input and produces an output. It will be our asynchronous "fetch image" task from the OPs example.
And parameter completion is the handler which gets invoked when all inputs have been processed. It's parameter contains the output of each transform function in an array.
The transform_each can be implemented as follows. First we need a "helper" function do_each.
do_each is actually the heart of the whole pattern for implementing loops in an asynchronous style, so you may take a closer look here:
void do_each(NSEnumerator* iter, transform_t task, NSMutableArray* outArray, completion_t completion)
{
id obj = [iter nextObject];
if (obj == nil) {
if (completion)
completion([outArray copy]);
return;
}
task(obj, ^(id result){
[outArray addObject:result];
do_each(iter, task, outArray, completion);
});
}
The interesting part here, and the "common asynchronous pattern" or "idiom" for implementing loops (as a for_each function) is that do_each will be invoked from the completion handler of the transform function. That may look like a recursion, but actually it is not.
Parameter iter points to the current object within the array which shall be processed.
It will also be used to determine the stop condition: when the enumerator points past the end, we get a nil result from method nextObject. This eventually stops the loop.
Otherwise, the transform function task will be called with the current object as input parameter. The object will be asynchronously processed as defined by the task. When finished, the task's completion handler will be invoked. It's parameter result will be the output of the transform function. The handler needs to add the result to the resulting array outArray. Then it invokes the helper do_each again. This seems to be a recursive call, but it is actually not: the former do_each has already been returned. This is just another invocation of do_each.
Once we have that, we can simply complete our transform_each function as shown below:
void transform_each(NSArray* inArray, transform_t task, completion_t completion) {
NSMutableArray* outArray = [[NSMutableArray alloc] initWithCapacity:[inArray count]];
NSEnumerator* iter = [inArray objectEnumerator];
do_each(iter, task, outArray, completion);
}
NSArray Category
For our convenience we can easily create a Category for NSArray with a "forEach" method which asynchronously processes the inputs in sequence:
#interface NSArray (AsyncExtension)
- (void) async_forEachApplyTask:(transform_t) task completion:(completion_t) completion;
#end
#implementation NSArray (AsyncExtension)
- (void) async_forEachApplyTask:(transform_t) task completion:(completion_t) completion {
transform_each(self, task, completion);
}
#end
A code example can be found here on Gist: transform_each
A much more sophisticated concept to solve common asynchronous patterns is to utilize "Futures" or "Promises". I've implemented the concept of a "Promise" for Objective-C in a small library: RXPromise.
The above "loop" can be implemented including a the capability to cancel the asynchronous tasks via RXPromise, and of course a lot more. Have fun ;)
I think I might just solve this problem. I am not sure about it. It just works. I am using AFNetwroking's enqueueBatchOfHTTPRequestOperations function.
So here is what I've got:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1*NSEC_PER_SEC), dispatch_get_current_queue(), ^{
bool ready = some_function();
if( ready ) {
do_smth_here()
} else {
//invoke this block one more time after 0.1 sec
}
});
The problem is how can I get the reference to the current block?
Instead of jumping through the hoops shown above, I typically declare an instance method that I can call that, internally, takes care of the retriggers as necessary. That way, any given block is one-shot, but the re-trigger creates a new block.
As long as the block creation isn't terribly expensive -- which it won't be if the state is coming from whatever encapsulates the instance method -- it is efficient enough and a heck of a lot simpler.
- (void) retriggerMethod
{
... do stuff here, assuming you want to do it on first invocation ...
dispatch_after( ..., ^{
[self retriggerMethod];
});
}
You can restructure it as needed. And you can easily add a BOOL instance variable if you want to protect against simultaneous retriggers, etc...
This also provides a convenient hook for canceling; just add a BOOL to the instance that indicates whether the next invocation should really do anything and re-schedule.
Jeffrey Thomas's answer is close, but under ARC, it leaks the block, and without ARC, it crashes.
Without ARC, a __block variable doesn't retain what it references. Blocks are created on the stack. So the callback variable points to a block on the stack. When you pass callback to dispatch_after the first time (outside of the block), dispatch_after successfully makes a copy of the block on the heap. But when that copy is invoked, and passes callback to dispatch_after again, callback is a dangling pointer (to the now-destroyed block on the stack), and dispatch_after will (usually) crash.
With ARC, a __block variable of block type (like callback) automatically copies the block to the heap. So you don't get the crash. But with ARC, a __block variable retains the object (or block) it references. This results in a retain cycle: the block references itself. Xcode will show you a warning on the recursive dispatch_after call: “Capturing 'callback' strongly in this block is likely to lead to a retain cycle”.
To fix these problems, you can copy the block explicitly (to move it from the stack to the heap under MRC) and set callback to nil (under ARC) or release it (under MRC) to prevent leaking it:
__block void (^callback)() = [^{
if(stop_) {
NSLog(#"all done");
#if __has_feature(objc_arc)
callback = nil; // break retain cycle
#else
[callback release];
#endif
} else {
NSLog(#"still going");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC), dispatch_get_current_queue(), callback);
}
} copy];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC), dispatch_get_current_queue(), callback);
Obviously you can drop the #if and just use the branch appropriate for your memory management.
I think this is the code your looking for:
__block void (^callback)();
callback = ^{
bool ready = some_function();
if( ready ) {
do_smth_here()
} else {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1*NSEC_PER_SEC), dispatch_get_current_queue(), callback);
}
};
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1*NSEC_PER_SEC), dispatch_get_current_queue(), callback);
Thanks to ^ Blocks Tips & Tricks
My problem is that I'm using dispatch_async(dispatch_get_main_queue(), ^(void) { ... }); to call a method asynchronously, in this method depending on some conditions i set a boolean to YES. When this boolean is read in this method, it's always read by it's old value which is NO.
The weird thing is that when i made a breakpoint on the line where the bool is checked, everything went fine and as intended !
EDIT:
Here is the code where the threads are spawned
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self drawFaceBoxesForFeatures:features forVideoBox:claporientation:curDeviceOrientation image:img];
});
The method itself
- (void)drawFaceBoxesForFeatures:(NSArray *)features forVideoBox:(CGRect)clap orientation: (UIDeviceOrientation)orientation image:(UIImage *)image;
{
if (![self getSendingRequestStatus]) {
NSLog(#"Sending req");
// send async request
dispatch_async(dispatch_get_main_queue(),^ {
sendingRequest = YES;
} );
}
}
It looks like you are modifying an ivar that was created outside of a block inside of the block. In order to do this and have the ivar hold the correct value, you are going to need to use the __block keyword like so:
#interface MyCoolClass : NSObject {
#private
__block int sendingRequest_;
}
As Jack Lawrence said in the commend above, "[the runtime] takes a snapshot of all of the relevant objects/variables at that point in time". The __block identifier will tell the runtime that it should not copy that ivar to the heap and will allow you to assign values to sendingRequest_ inside of a block, even if that block is simply being run on the main thread.
A lot of good information to start with (including the above) can be found in the Blocks Programming Guide.
When primitives are passed into a block they are copied. So if you put a primitive local or instance variable in a block and then later change it either in the same method that created the block (after the block creation) or another method it won't have any effect on the variable in the block. In the case of a local variable, just make sure you make any necessary changes before block creation. In the case of instance variables you could try accessing the instance variable by using some C: self->iVar or declare it as a property and access it through the property accessor: self.iVar.
Is there a way to verify that a method has been called 'x' amount of times?
Looking at the test file for OCMock, it seems that you need to have the same number of expects as you have calls. So if you call someMethod three times, you need to do...
[[mock expect] someMethod];
[[mock expect] someMethod];
[[mock expect] someMethod];
...test code...
[mock verify];
This seems ugly though, maybe you can put them in a loop?
I've had success by leveraging the ability to delegate to a block:
OCMStub([mock someMethod]).andDo(^(NSInvocation *invocation)
{ /* block that handles the method invocation */ });
Inside the block, I just increment a callCount variable, and then assert that it matches the expected number of calls. For example:
- (void)testDoingSomething_shouldCallSomeMethodTwice {
id mock = OCMClassMock([MyClass class]);
__block int callCount = 0;
OCMStub([mock someMethod]).andDo(^(NSInvocation *invocation) {
++callCount;
});
// ...exercise code...
int expectedNumberOfCalls = 2;
XCTAssertEqual(callCount, expectedNumberOfCalls);
}
The block should be invoked each time someMethod is called, so callCount should always be the same as the number of times the method was actually called.
If you need to check if a method is only called once, you can do it like this
[self.subject doSomething];
OCMVerify([self.mock method]);
OCMReject([self.mock method]);
[self.subject doSomething];