Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I modify an ObjC method's parameters within a block?

If I have an Objective-C method that takes an object parameter, and said method uses a block to do its work internally, is there a way to modify that object from within the block?

It is my understanding that blocks capture variables from their parent scope by referring to them within the block, and that they are copied by default. And if I want to be able to modify rather than work with a copy of a surrounding object, I can prefix its declaration with __block, but I'm unable to do so with method parameters since I didn't declare it myself, right?

For example:

- (void)doWorkWithString:(NSString *)someString
{
    [NSFoo doAwesomeClassMethodWithBlock:^{
        // How can I modify someString here directly?
        // By just changing someString, I'm changing the captured copy
    }];
}
like image 269
Collin Allen Avatar asked Nov 13 '12 05:11

Collin Allen


People also ask

What does __ block do in Objective-C?

The __block Storage Type __block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable's lexical scope.

How do I create an instance of a class in Objective-C?

There is basically one way to do this: you send a class the alloc message. The alloc class method is implemented by the NSObject class, the root class from which all other classes inherit. It causes memory to be set aside for the instance so that an instance pointer can point to it.

How do you write blocks in Objective-C?

^blockName: Always remember that the block name is preceded by the ^ symbol. The block name can be any string you like, just like you name any other variable or method. Remember that both the ^ and the block name are enclosed in parentheses ().

How do you declare a method in Objective-C?

An Objective-C method declaration includes the parameters as part of its name, using colons, like this: - (void)someMethodWithValue:(SomeType)value; As with the return type, the parameter type is specified in parentheses, just like a standard C type-cast.


2 Answers

"that takes an object parameter"

First of all, you are almost certainly confused by the fact that you cannot have a parameter or variable of object type. You can only have pointers to objects. So yes, non-__block variables that are captured by a block are copied by the block. But the variables here are either primitives or object pointers, not "objects".

If you only need to mutate the object that an object pointer points to, and that does not involve changing the pointer to point to another object, then you are not changing the variable. And since you are not changing the variable, all this "copying the variable" and __block stuff is completely irrelevant.

like image 93
newacct Avatar answered Nov 25 '22 22:11

newacct


What you say about capture is correct; what you probably want to do is supply the objects that should be the subject of the block as arguments to it — much like if you were calling a C function. So e.g.

void (^ someBlock)(NSString *) =
    ^(NSString *someString)
    {
        NSLog(@"length is %d", [someString length]);
    };

...

someBlock(@"String 1");
someBlock(@"A second string");
like image 35
Tommy Avatar answered Nov 25 '22 23:11

Tommy