I've always thought, that copy
would just copy the object. In case of blocks, it's a bit different, but I'm really surprised how it works in following case.
I have and instance objectA
and objectB
of the following class:
@interface MyObject : NSObject
@property(nonatomic, copy) void (^myHandler)(CGFloat progress);
@property(nonatomic) CGFloat progress;
@end
objectA
is empty. objectB
has the values set. In some point of app, I want to discard objectB
and leave only objectA
, so I need to inject these two values of objectB
to objectA
:
MyObject *objectA = [MyObject new];
if (nowIWantToGetRidOfB) {
objectA.progress = objectB.progress;
objectA.myHandler = objectB.myHandler;
objectB.myHandler = nil;
objectB = nil; // that's just an example to show it gets released after this code
}
I'd expect the block to be copied to the new objectA
instance and objectB
to be released (because there is no reference pointing to it).
But instead, nothing happens. The block, even though it should, is never again evaluated. Should I copy it in another way? Can someone explain what's and why is happening or point to some documentation which will explain it?
-- edit --
Snippet how the block is set:
MyObject *objectB = [MyObject new];
objectB.progress = 0.5f;
[objectB setProgressHandler:^(CGFloat progress) {
NSLog(@"example");
}];
Beside the question in my comment, this likely does not work anyway.
Blocks are not only a snippet of code, but closures. That means that they do a snapshot of the point in time they are created. If such a block refers to objectB
at creation time, after copying they will still refer to that object, even you store the block or a copy of it to objectA
. (Instance objects does not have identifiers, however, I think I understand what you mean.)
So, having this code:
MyObject *objectB = …;
objectB.handler = ^(CGFloat progress)
{
… objectB …
}
Something will be done with objectB
. After copying (here explicitly) …
MyObject *objectA = …;
objectA.handler = objectB.handler;
… it is still the same: Something will be done with objectB
, because it is still referred by the block.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.