NSBlockOperation and objects in the block

324 Views Asked by At

Here is the simple code:

// let's assume that I have to allocate this variable with alloc/init
NSString *someString = [[NSString alloc] initWithFormat:"%@", @"someString"];

NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction: someString];
}];

[queue addOperation:op]

[someString release];

This code will crash when nsblockoperation gets ran since someString is released. What is the best practice to prevent this?

Thank you.

EDIT: ARC is not a choice as it's not my decision to make. Any way to get around this in MRC?

EDIT2: What about following code? Would it work?

// let's assume that I have to allocate this variable with alloc/init
NSString *someString = [[NSString alloc] initWithFormat:"%@", @"someString"];

[someString retain]
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction: someString];
  [someString release]
}];

[queue addOperation:op]

[someString release];
2

There are 2 best solutions below

6
On BEST ANSWER

You really should use Automatic Reference Counting, and simplify the code to

// let's say the variable is allocated with alloc/init
NSString *someString = @"someString";

NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction: someString];
}];

[queue addOperation:op]

If you really have to use Manual Reference Counting you can do this:

// let's assume that I have to allocate this variable with alloc/init
NSString *someString = [[NSString alloc] initWithFormat:"%@", @"someString"];

NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction: someString];
  [someString release]
}];

[queue addOperation:op]

I know its just example code, but if it were not you could also do this... ;)

NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction:@"someString"];
}];

[queue addOperation:op]
0
On
// let's say the variable is allocated with alloc/init
NSString *someString = [[[NSString alloc] initWithFormat:"%@", @"someString"] autorelease];

NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction: someString];
}];

[queue addOperation:op];

There are hundreds of thousands of apps around that need to be maintained and do not use ARC. Wrap the string in an autorelease. I think that should work but I did not test.