0

Is it possible to run a block when a delegate receives a message?

For example, if I had a framework that took a void block as a parameter (we'll call it the "success" block), and was using an NSURLConnection delegate to do stuff with those method arguments, when I receive a response from the webpage, how can I call the "success" block passed in the method parameters?

This is really hard for me to explain, and I obviously don't have any code for this, but I can clarify if you have any questions.

Zane Helton
  • 1,044
  • 1
  • 14
  • 34

1 Answers1

3

You absolutely can. That is how all completion handlers / callbacks work. In fact, that is what a block is for.

To take a simple example, consider this NSURLConnection class method:

+ (void)sendAsynchronousRequest:(NSURLRequest *)request
                          queue:(NSOperationQueue *)queue
              completionHandler:(void (^)(NSURLResponse *response,
                                          NSData *data,
                                          NSError *connectionError))handler

For the third parameter, you pass a block. And when the request is all over, some time in the future, what does NSURLConnection do? It calls the block.

So, you can do exactly the same that NSURLConnection is doing. You can write a method that takes a block, you hold on to the block, you do something that perhaps takes some time, and then later you call the block.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • How do you store / call the block? – Zane Helton Apr 22 '15 at 19:01
  • You store it the same way you store anything - in a variable / property. And you call it the same way you call any function: you say its name followed by parentheses (you know, with arguments in them). – matt Apr 22 '15 at 19:04
  • I'll try it out when I get home, I had no idea this was possible! Marking as correct answer assuming you're right, thanks! – Zane Helton Apr 22 '15 at 19:05
  • You might want to read Apple's docs: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html – matt Apr 22 '15 at 19:05
  • 1
    "I had no idea this was possible" But then one has to wonder what you thought a block _was_ all this time. Every block you've ever used works this way. A block is to call. Otherwise what's the point of it? :) The only difference is that you were always letting someone _else_ receive it, hang on to it, and call it. Now, _you_ will receive it, hang on to it, and call it. – matt Apr 22 '15 at 19:06
  • 1
    @Vig I've worked with blocks before and can honestly say, this website is a life savor. Love it. – Zane Helton Apr 22 '15 at 19:06
  • @matt To answer your rhetorical question: Magic. – Zane Helton Apr 22 '15 at 19:08
  • "To answer your rhetorical question: Magic" Oh. Well if you already knew the answer, why are you asking in the first place? :)))))) – matt Apr 22 '15 at 19:08
  • 1
    Here is an example from my own code, where I do something _very_ similar to what you are describing: https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/iOS7bookExamples/bk2ch24p842downloader/ch37p1099downloader/MyDownloader.m – matt Apr 22 '15 at 19:11
  • That was extremely helpful @matt, thanks. Now I have a model requesting data from a website with a completion handler, BUT if I were to for example send a message to that method twice in a row without waiting for the first one to finish, the second message overrides the first message and it screws stuff up. Is there anyway around this? EDIT: I could put the second call in the completion handler for the first call, but is there any easier way? – Zane Helton Apr 23 '15 at 05:21
  • @ZaneHelton But that's a completely separate question. And a very interesting one! I wish you'd ask it as a real question, and please blip me in a comment here and point me to it. Thanks!!! But please note - my example that I pointed you to works perfectly if MyDownloader receives a new "start downloading" request while it is already downloading something, because it associates each completion handler with that individual download. So nothing gets overridden. – matt Apr 23 '15 at 14:43