Копировать блок между объектами

Я всегда думал, что copy просто скопировать объект. В случае блоков все немного по-другому, но я очень удивлен, как это работает в следующем случае.

У меня есть и экземпляр objectA а также objectB следующего класса:

@interface MyObject : NSObject
@property(nonatomic, copy) void (^myHandler)(CGFloat progress);
@property(nonatomic) CGFloat progress;
@end

objectA пустой. objectB имеет установленные значения. В какой-то момент приложения я хочу отказаться objectB и оставить только objectAтак что мне нужно ввести эти два значения objectB в 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
}

Я ожидаю, что блок будет скопирован в новый objectA экземпляр и objectB быть выпущенным (потому что нет ссылки, указывающей на это).

Но вместо этого ничего не происходит. Блок, даже если и должен, никогда больше не оценивается. Должен ли я скопировать его по-другому? Может кто-нибудь объяснить, что и почему происходит, или указать на какую-то документацию, которая это объяснит?

-- редактировать --

Фрагмент, как установлен блок:

MyObject *objectB = [MyObject new];
objectB.progress = 0.5f;
[objectB setProgressHandler:^(CGFloat progress) {
    NSLog(@"example");
}];

1 ответ

Помимо вопроса в моем комментарии, это, вероятно, не работает в любом случае.

Блоки - это не только фрагмент кода, но и замыкания. Это означает, что они делают снимок момента времени, когда они были созданы. Если такой блок относится к objectB во время создания, после копирования они все равно будут ссылаться на этот объект, даже если вы сохраните блок или его копию в objectA, (Объекты экземпляра не имеют идентификаторов, однако, я думаю, я понимаю, что вы имеете в виду.)

Итак, имея этот код:

MyObject *objectB = …;
objectB.handler = ^(CGFloat progress)
{
  … objectB …
}

Что-то будет сделано с objectB, После копирования (здесь явно) …

MyObject *objectA = …;
objectA.handler = objectB.handler;

... это все то же самое: что-то будет сделано с objectB потому что он все еще ссылается на блок.

Другие вопросы по тегам