Rectangle 27 60

On a table with 158k pseudo-random rows (usr_id uniformly distributed between 0 and 10k, trans_id uniformly distributed between 0 and 30),

xxx_cost
  • Quassnoy's query has a cost estimate of 745k (!), and completes in 1.3 seconds (given a compound index on (usr_id, trans_id, time_stamp))
  • Bill's query has a cost estimate of 93k, and completes in 2.9 seconds (given a compound index on (usr_id, trans_id))
  • Query #1 below has a cost estimate of 16k, and completes in 800ms (given a compound index on (usr_id, trans_id, time_stamp))
usr_id
EXTRACT(EPOCH FROM time_stamp)
trans_id
  • Query #3 below (Postgres 8.4+) has a cost estimate and completion time comparable to (or better than) query #2 (given a compound index on (usr_id, time_stamp, trans_id)); it has the advantage of scanning the lives table only once and, should you temporarily increase (if needed) work_mem to accommodate the sort in memory, it will be by far the fastest of all queries.

All times above include retrieval of the full 10k rows result-set.

Your goal is minimal cost estimate and minimal query execution time, with an emphasis on estimated cost. Query execution can dependent significantly on runtime conditions (e.g. whether relevant rows are already fully cached in memory or not), whereas the cost estimate is not. On the other hand, keep in mind that cost estimate is exactly that, an estimate.

The best query execution time is obtained when running on a dedicated database without load (e.g. playing with pgAdminIII on a development PC.) Query time will vary in production based on actual machine load/data access spread. When one query appears slightly faster (<20%) than the other but has a much higher cost, it will generally be wiser to choose the one with higher execution time but lower cost.

When you expect that there will be no competition for memory on your production machine at the time the query is run (e.g. the RDBMS cache and filesystem cache won't be thrashed by concurrent queries and/or filesystem activity) then the query time you obtained in standalone (e.g. pgAdminIII on a development PC) mode will be representative. If there is contention on the production system, query time will degrade proportionally to the estimated cost ratio, as the query with the lower cost does not rely as much on cache whereas the query with higher cost will revisit the same data over and over (triggering additional I/O in the absence of a stable cache), e.g.:

cost | time (dedicated machine) |     time (under load) |
-------------------+--------------------------+-----------------------+
some query A:   5k | (all data cached)  900ms | (less i/o)     1000ms |
some query B:  50k | (all data cached)  900ms | (lots of i/o) 10000ms |

Do not forget to run ANALYZE lives once after creating the necessary indices.

-- incrementally narrow down the result set via inner joins
--  the CBO may elect to perform one full index scan combined
--  with cascading index lookups, or as hash aggregates terminated
--  by one nested index lookup into lives - on my machine
--  the latter query plan was selected given my memory settings and
--  histogram
SELECT
  l1.*
 FROM
  lives AS l1
 INNER JOIN (
    SELECT
      usr_id,
      MAX(time_stamp) AS time_stamp_max
     FROM
      lives
     GROUP BY
      usr_id
  ) AS l2
 ON
  l1.usr_id     = l2.usr_id AND
  l1.time_stamp = l2.time_stamp_max
 INNER JOIN (
    SELECT
      usr_id,
      time_stamp,
      MAX(trans_id) AS trans_max
     FROM
      lives
     GROUP BY
      usr_id, time_stamp
  ) AS l3
 ON
  l1.usr_id     = l3.usr_id AND
  l1.time_stamp = l3.time_stamp AND
  l1.trans_id   = l3.trans_max
-- cheat to obtain a max of the (time_stamp, trans_id) tuple in one pass
-- this results in a single table scan and one nested index lookup into lives,
--  by far the least I/O intensive operation even in case of great scarcity
--  of memory (least reliant on cache for the best performance)
SELECT
  l1.*
 FROM
  lives AS l1
 INNER JOIN (
   SELECT
     usr_id,
     MAX(ARRAY[EXTRACT(EPOCH FROM time_stamp),trans_id])
       AS compound_time_stamp
    FROM
     lives
    GROUP BY
     usr_id
  ) AS l2
ON
  l1.usr_id = l2.usr_id AND
  EXTRACT(EPOCH FROM l1.time_stamp) = l2.compound_time_stamp[1] AND
  l1.trans_id = l2.compound_time_stamp[2]

Finally, as of version 8.4, Postgres supports Window Function meaning you can write something as simple and efficient as:

-- use Window Functions
-- performs a SINGLE scan of the table
SELECT DISTINCT ON (usr_id)
  last_value(time_stamp) OVER wnd,
  last_value(lives_remaining) OVER wnd,
  usr_id,
  last_value(trans_id) OVER wnd
 FROM lives
 WINDOW wnd AS (
   PARTITION BY usr_id ORDER BY time_stamp, trans_id
   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
 );

By a compound index on (usr_id, trans_id, times_tamp), do you mean something like "CREATE INDEX lives_blah_idx ON lives (usr_id, trans_id, time_stamp)"? Or should I create three separate indexes for each column? I should stick with the default of "USING btree", right?

Yes to the first choice: I mean CREATE INDEX lives_blah_idx ON lives (usr_id, trans_id, time_stamp). :) Cheers.

Thanks for even doing the cost comparison vladr! Very complete answer!

@vladr I just came across your answer. I am a bit confused, as you say query 1 has a cost of 16k and query 2 a cost of 14k. But further down in the table you say query 1 has a cost of 5k and query 2 has a cost of 50k. So which query is a preferred one to use? :) thanks

@Kave, the table is for a hypothetical pair of queries to illustrate an example, not the OP's two queries. Renaming to reduce confusion.

sql - PostgreSQL - fetch the row which has the Max value for a column ...

sql postgresql query-optimization cbo cost-based-optimizer
Rectangle 27 1

I'm not gonna suggest what you can do with your JMS backend - its probably not used well or maybe it is - I'm not sure.

We implemented something similar and here is what we ended up with (our backend implmentation was completely different, for a different use case, but the "async user exp" matches) :

  • Allow user to submit a request.
  • Once (1) is received, submit the job to the backend (JMS etc...) and tie it to a job id
  • The response of (1) is a this (permanent or temporary) handle - the job id, for example
  • The backend implementation should end by setting the status of the job
  • Allow users to poll for the status of the job (via the handle you gave them)
  • If the job status is "in progress", tell them so (with probably an estimated time for completion - so that they dont unnecessarily waste time polling & burdening you)
  • If the status is "done successfully", report that to the user, with the other data (url etc...) the user would need to access the result

polling need not be a webserivce per se - as suggested in another answers, it could be an end point, you would be polling on, via AJAX to find the status of the job

actually a very good implementation of this is in Yahoo's Delicious page for "importing bookmark files" : secure.delicious.com/settings/bookmarks/import

What Java/Design Patterns can be used for Long Running Synchronous Pro...

java java-ee jms scalability
Rectangle 27 42

I've tried opening your project, and the completion seems to be working just fine for me.

The only thing I can think of is to try to delete your entire NB cache, which should be located in $HOME/.netbeans/$VERSION/var/cache/. This is a wild guess

Create a backup first

If that fails, maybe you should try creating a new project, maybe that will kick NB in the butt.

Note that in NB 7.2 beta, the cache has moved to $HOME/.cache/netbeans/$VERSION.

I was really hesistant to try this, but it did actually fix the problem. (rm -rf'ing the cache)

had some odd issues with code completion in NB6.8 for python. Clearing the cache solved my problems.

Worked beautifully with 7.2 when my "hints" suddenly went away. On Linux I did cd ~/.cache/netbeans/ ; tar cvfz backup.tgz ./7.2.1; rm -rf 7.2.1. My project is rather large so I had to wait about 10-12 minutes for the background scan to complete, but once it finished the previously missing auto-complete was back in action! Thanks!

@JeyKeu: Sorry mate, no idea, I'm still on 10.10... Could it be a packaging issue? Have you tried a non-repo version (or vice versa if it is a repo version)?

NetBeans PHP code completion - Stack Overflow

netbeans code-completion
Rectangle 27 56

@weaver From the docs, it looks like either global completion has to be enabled or a specific eval statement needs to be added to bashrc. Is there a way to create a completion script and let bash know where the script is?

@balki: I'm not sure exactly what you're trying to do, but you can run register-python-argcomplete my-script.py > completion-script.sh. You can similarly save the global completion activation script as per the docs. Then you have to somehow get the user to source that script (running the script won't work, since that's a subprocess).

Is it possible to distribute the completion-script.sh with the package so that a user does not need to eval anything?

Python argparse and bash completion - Stack Overflow

python argparse bash-completion
Rectangle 27 47

Not related to completion, but you could supress that output by putting the call in a subshell:

(echo "Hello I'm a background task" &)

Thanks, that definitely works. Unfortunately, when running a script like this from a bash-completion function, it appears that bash waits until the subprocess is complete before giving completion results. This is unfortunate as it means it doesn't appear to be possible to make background workers be triggered by bash-completion.

You can't use this if you want to wait for the background job to finish.

Running bash commands in the background without printing job and proce...

bash bash-completion
Rectangle 27 265

All the other answers are correct, but just for completion

A function is declared in the following manner:

return-type function-name(parameter-list,...) { body... }

return-type is the variable type that the function returns. This can not be an array type or a function type. If not given, then int is assumed.

function-name is the name of the function.

parameter-list is the list of parameters that the function takes separated by commas. If no parameters are given, then the function does not take any and should be defined with an empty set of parenthesis or with the keyword void. If no variable type is in front of a variable in the paramater list, then int is assumed. Arrays and functions are not passed to functions, but are automatically converted to pointers. If the list is terminated with an ellipsis (,...), then there is no set number of parameters. Note: the header stdarg.h can be used to access arguments when using an ellipsis.

And again for the sake of completeness. From C11 specification 6:11:6 (page: 179)

use of function declarators with empty parentheses

c - Why does a function with no parameters (compared to the actual fun...

c parameters function-prototypes function-parameter
Rectangle 27 140

Set the UIApplication statusBarStyle in the completion block of presentViewController for your MFMailComposeViewController. i.e.

MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
    [self.navigationController presentViewController:mailVC animated:YES completion:^{
        [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    }];

If you make that change in your Info.plist, I don't think it matters where you do the setStatusBarStyle, as it becomes the global setting for the app.

this shouldt be marked as the correct answer since preferredStatusBarStyle at this point on is useless

@mackinra: Not exactly. I have it set on my plist and app delegate, but MailViewComposeViewController overrides it to black from white in my case. This solution has fixed it, as weird as it is.

[self presentViewController:mailVC...
[self.navigationController...

ios7 - MFMailComposeViewController in iOS 7 statusbar are black - Stac...

ios ios7 mfmailcomposeviewcontroll
Rectangle 27 140

Set the UIApplication statusBarStyle in the completion block of presentViewController for your MFMailComposeViewController. i.e.

MFMailComposeViewController *mailVC = [[MFMailComposeViewController alloc] init];
    [self.navigationController presentViewController:mailVC animated:YES completion:^{
        [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    }];

If you make that change in your Info.plist, I don't think it matters where you do the setStatusBarStyle, as it becomes the global setting for the app.

this shouldt be marked as the correct answer since preferredStatusBarStyle at this point on is useless

@mackinra: Not exactly. I have it set on my plist and app delegate, but MailViewComposeViewController overrides it to black from white in my case. This solution has fixed it, as weird as it is.

[self presentViewController:mailVC...
[self.navigationController...

ios7 - MFMailComposeViewController in iOS 7 statusbar are black - Stac...

ios ios7 mfmailcomposeviewcontroll
Rectangle 27 68

extension UITableView {
    func reloadData(completion: ()->()) {
        UIView.animateWithDuration(0, animations: { self.reloadData() })
            { _ in completion() }
    }
}

...somewhere later...

tableView.reloadData {
    println("done")
}
[UIView animateWithDuration:0 animations:^{
    [myTableView reloadData];
} completion:^(BOOL finished) {
    //Do something after that...
}];

That is equivalent to dispatching something on the main thread in the "near future". It's likely you're just seeing the table view render the objects before the main thread deques the completion block. It's not advised to do this kind of hack in the first place, but in any case, you should use dispatch_after if you're going to attempt this.

The Rob's solution is good but doesn't work if there are no rows in the tableview. Aviel's solution has the advantage to work even when the table contains no lines but only sections.

@Christophe As of now, I was able to use Rob's update in a table view without any rows by overriding in my Mock view controller the tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int method and inserting in my override whatever I wanted to notify that the reload had finished.

objective c - How to tell when UITableVIew has completed ReloadData? -...

objective-c uitableview
Rectangle 27 45

I ran into this problem as well and came up with this code snippet. This will automatically give you completion for all aliases. Run it after declaring all (or any) alias.

# wrap_alias takes three arguments:
# $1: The name of the alias
# $2: The command used in the alias
# $3: The arguments in the alias all in one string
# Generate a wrapper completion function (completer) for an alias
# based on the command and the given arguments, if there is a
# completer for the command, and set the wrapper as the completer for
# the alias.
function wrap_alias() {
  [[ "$#" == 3 ]] || return 1

  local alias_name="$1"
  local aliased_command="$2"
  local alias_arguments="$3"
  local num_alias_arguments=$(echo "$alias_arguments" | wc -w)

  # The completion currently being used for the aliased command.
  local completion=$(complete -p $aliased_command 2> /dev/null)

  # Only a completer based on a function can be wrapped so look for -F
  # in the current completion. This check will also catch commands
  # with no completer for which $completion will be empty.
  echo $completion | grep -q -- -F || return 0

  local namespace=alias_completion::

  # Extract the name of the completion function from a string that
  # looks like: something -F function_name something
  # First strip the beginning of the string up to the function name by
  # removing "* -F " from the front.
  local completion_function=${completion##* -F }
  # Then strip " *" from the end, leaving only the function name.
  completion_function=${completion_function%% *}

  # Try to prevent an infinite loop by not wrapping a function
  # generated by this function. This can happen when the user runs
  # this twice for an alias like ls='ls --color=auto' or alias l='ls'
  # and alias ls='l foo'
  [[ "${completion_function#$namespace}" != $completion_function ]] && return 0

  local wrapper_name="${namespace}${alias_name}"

  eval "
function ${wrapper_name}() {
  let COMP_CWORD+=$num_alias_arguments
  args=( \"${alias_arguments}\" )
  COMP_WORDS=( $aliased_command \${args[@]} \${COMP_WORDS[@]:1} )
  $completion_function
  }
"

  # To create the new completion we use the old one with two
  # replacements:
  # 1) Replace the function with the wrapper.
  local new_completion=${completion/-F * /-F $wrapper_name }
  # 2) Replace the command being completed with the alias.
  new_completion="${new_completion% *} $alias_name"

  eval "$new_completion"
}

# For each defined alias, extract the necessary elements and use them
# to call wrap_alias.
eval "$(alias -p | sed -e 's/alias \([^=][^=]*\)='\''\([^ ][^ ]*\) *\(.*\)'\''/wrap_alias \1 \2 '\''\3'\'' /')"

unset wrap_alias
((COMP_CWORD+=$num_alias_arguments))

Wow, that's awesome -- thanks! wrap_alias chokes on double quotes in the alias definition, and I guess it doesn't make much sense for multi-command aliases (alias 'foo=bar; baz'), so I'm putting an extra | grep -v '[";|&]' after the alias -p. Also, it gets a bit slow for hundreds of alias definitions, but I'm happy to confirm that using echo instead of eval and piping the output into a cache file (which can then be eval'ed in one go) works fine and is super-fast.

Another hint: wrap_alias requires the completions to be set up, so I had to move source /etc/bash_completion in front of the wrap_alias code.

let COMP_CWORD+=$num_alias_arguments
let \"COMP_CWORD+=$num_alias_arguments\"

See the updated version of this script at superuser.com/a/437508/102281 (for example, I added support for COMP_LINE and COMP_POINT which are required for some git completions).

git - How do I get bash completion to work with aliases? - Stack Overf...

git bash shell unix autocomplete
Rectangle 27 10

If it is assumed that the completion handler is to be run on the main thread, then no queue needs to be provided. An example would be UIView's animations methods:

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

Otherwise, the API usually asks the caller to provide a queue:

[foo doSomethingWithCompletion:completion targetQueue:yourQueue];

My suggestion is to follow this pattern. If it is unclear which queue the completion handler should be called, the caller should supply it explicitly as a parameter.

UIDocument saveToURL:forSaveOperation:completionHandler:

+1 Create your own serial queue and run the method and the completion block on that queue.

I would argue that this is a bug in UIDocument. It shouldn't be assuming that the originating queue has the behaviors that it wants.

objective c - dispatch_async and calling a completion handler on the o...

objective-c ios grand-central-dispatch
Rectangle 27 9

Have you provided the completion Selector?

...
UIImageWriteToSavedPhotosAlbum(imageView.image!, self, "image:didFinishSavingWithError:contextInfo:", nil) 
...



func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo:UnsafePointer<Void>) {
    if error == nil {
        let ac = UIAlertController(title: "Saved!", message: "Your altered image has been saved to your photos.", preferredStyle: .Alert)
        ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
        presentViewController(ac, animated: true, completion: nil)
    } else {
        let ac = UIAlertController(title: "Save error", message: error?.localizedDescription, preferredStyle: .Alert)
        ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
        presentViewController(ac, animated: true, completion: nil)
    }
}

ios - saving an image to photos library using Swift 2.0 - Stack Overfl...

ios swift uiimagepickercontroller imagelibrary
Rectangle 27 5

Pretty easy, pass funcToCall() as a completion parameter (important note - I'm using curly braces here):

viewController.dismissViewControllerAnimated(true, completion: { 
    funcToCall()
})
completion

The block to execute after the view controller is dismissed. This block has no return value and takes no parameters. You may specify nil for this parameter.

then the problem were i wasn't using the curly brackets? however, it works but it seems only partially. when i try to present a new viewController i still get this error: Attempt to present viewController3 whose view is not in the window hierarchy! but then somehow it presents it. it drives me nuts

i'll try to explain it better. i'm dismissing the vc2 with completion: notification and observer in vc1 that triggers segueWithIdentifier when the vc2 is supposedly dismissed, but then i was getting the "Attempt to present viewController3 whose view is not in the window hierarchy!" error. now i'm still getting it but then the segue is executed and i'm not sure if this could bring future issues.

i thought the problem appears due to the vc2 wasn't fully dismissed.

i'm not sure that this tread stackoverflow.com/questions/26022756/ can apply to this issue because when i change the way i'm presenting the VC i.e modal presentation, i'm getting this warning message: "Warning: Attempt to present vc3 on vc1 while a presentation is in progress!" should i post a new question explaining the issue? edit: that's why i think the problem is vc2 is still active when the vc3 is presenting

ios - How to properly dismiss modal viewcontroller with completion han...

ios swift uiviewcontroller
Rectangle 27 3

You should pass the completion handler block inside the argument. Make the return type to void.

[calenderView calendarMonthView:monthView marksFromDate:startDate toDate:lastDate completionHandler:^(NSarray *dataArray){
//Process data array over here
}];

- (void) calendarMonthView:(TKCalendarMonthView*)monthView marksFromDate:(NSDate*)startDate toDate:(NSDate*)lastDate completionHandler:(void (^)(NSArray*))completionBlock{
    AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
    _currentStart = startDate;
    _currentEnd = lastDate;

    if(appDelegate.internetActive){
        Webservice *web = [[Webservice alloc]init];
        [web fetchAppointmentsOnCompletionFor:startDate andEnd:lastDate OnCompletion:^(BOOL finished) {
            if(finished){
                [self generateRandomDataForStartDate:startDate endDate:lastDate];
                 completionBlock(self.dataArray);
            }
        }];
    }
    completionBlock(self.dataArray);
}

In the caller code handle completion block with response array received as argumnet.

I think this is the way to go! Can you please help me also how I should handle the completion ?

ios - Return an array after a completion block has finished - Stack Ov...

ios iphone objective-c objective-c-blocks
Rectangle 27 4

Pretty easy, pass funcToCall() as a completion parameter (important note - I'm using curly braces here):

viewController.dismissViewControllerAnimated(true, completion: { 
    funcToCall()
})
completion

The block to execute after the view controller is dismissed. This block has no return value and takes no parameters. You may specify nil for this parameter.

then the problem were i wasn't using the curly brackets? however, it works but it seems only partially. when i try to present a new viewController i still get this error: Attempt to present viewController3 whose view is not in the window hierarchy! but then somehow it presents it. it drives me nuts

i'll try to explain it better. i'm dismissing the vc2 with completion: notification and observer in vc1 that triggers segueWithIdentifier when the vc2 is supposedly dismissed, but then i was getting the "Attempt to present viewController3 whose view is not in the window hierarchy!" error. now i'm still getting it but then the segue is executed and i'm not sure if this could bring future issues.

i thought the problem appears due to the vc2 wasn't fully dismissed.

i'm not sure that this tread stackoverflow.com/questions/26022756/ can apply to this issue because when i change the way i'm presenting the VC i.e modal presentation, i'm getting this warning message: "Warning: Attempt to present vc3 on vc1 while a presentation is in progress!" should i post a new question explaining the issue? edit: that's why i think the problem is vc2 is still active when the vc3 is presenting

ios - How to properly dismiss modal viewcontroller with completion han...

ios swift uiviewcontroller
Rectangle 27 17

  • Control.Invoke: Executes on the UI thread, but calling thread waits for completion before continuing.
  • Control.BeginInvoke: Executes on the asynchronous UI thread, and calling thread doesn't wait for completion.

and from MSDN:

BeginInvoke executes the specified delegate asynchronously on the thread that the control's underlying handle was created on.

To sum it up, BeginInvoke is asynchronous. When BeginInvoke is called from the UI thread the request will be executed in parallel with the UI thread. Which means it may not execute until after the currently executing method has returned. So in this case the text box will never appear to update because the for loop will not be interrupted, as the calling thread will not wait for this event to be completed before continuing.

Alternatively, Invoke is synchronous. The text box will be updated because the calling thread will wait for the call to complete before continuing execution.

A minor point - it doesn't get executed when the method returns, it's done as a fire and forget - it's fired off into the COM/winapi ether

c# - Invoke and BeginInvoke - Stack Overflow

c# asynchronous invoke begininvoke
Rectangle 27 17

  • Control.Invoke: Executes on the UI thread, but calling thread waits for completion before continuing.
  • Control.BeginInvoke: Executes on the asynchronous UI thread, and calling thread doesn't wait for completion.

and from MSDN:

BeginInvoke executes the specified delegate asynchronously on the thread that the control's underlying handle was created on.

To sum it up, BeginInvoke is asynchronous. When BeginInvoke is called from the UI thread the request will be executed in parallel with the UI thread. Which means it may not execute until after the currently executing method has returned. So in this case the text box will never appear to update because the for loop will not be interrupted, as the calling thread will not wait for this event to be completed before continuing.

Alternatively, Invoke is synchronous. The text box will be updated because the calling thread will wait for the call to complete before continuing execution.

A minor point - it doesn't get executed when the method returns, it's done as a fire and forget - it's fired off into the COM/winapi ether

c# - Invoke and BeginInvoke - Stack Overflow

c# asynchronous invoke begininvoke
Rectangle 27 17

Just for completion, here is a code example indicating the differences:

$http.get('/someURL')
.success(function(data, status, header, config) {
    // success handler
})
.error(function(data, status, header, config) {
    // error handler
});
$http.get('/someURL')
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
})
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
})
.then(function(response) {
    // success handler
}, function(response) {
    // error handler
}).

great!, do you have an example where the concatenation can be useful ?

The idea is that the "then" approach is more useful, since you can more easy write asynchronous operations one after the other.

angularjs - Angular HttpPromise: difference between `success`/`error` ...

angularjs promise
Rectangle 27 3

It won't create a retain cycle, your instance doesn't hold a strong reference to the completion block. However I would prefer not calling the super implementation like this, maybe something like this

-(void)cancelAfterRequest 
{
    [NSURLConnection sendAsynchronousRequest:request 
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
         [self cancel];
    }];
}

ios - Correct way to access super in completion block - Stack Overflow

ios objective-c automatic-ref-counting objective-c-blocks retain-cycle