Понимание модификатора Objective-C++ __block

Мне нужно выполнить некоторое обслуживание приложения Objective-C (обновить его для использования нового API), и, поскольку я никогда раньше не использовал этот язык, я немного запутался.

У меня есть класс Objective-C++, который реализует интерфейс из моего API, и он используется внутри блока, однако всякий раз, когда к нему обращаются внутри блока, происходит сбой с ошибкой нарушения прав доступа (EXC_BAD_ACCESS).

Дальнейшее исследование показывает, что ни один из конструкторов рассматриваемого объекта не вызывается. Он объявлен в пределах области действия и использует модификатор __block.

Чтобы попытаться понять это, я сделал быстрое приложение и обнаружил, что там происходит то же самое:

class Foo
{
public:
    Foo() : value(1) { printf("constructor"); }
    void addOne() { ++value; printf("value is %d", value); }
private:
    int value;
};

void Bar()
{
    Foo foo1; // prints "constructor"
    __block Foo foo2; // doesn't print anything

    foo1.addOne(); //prints "2"
    foo2.addOne(); //prints "1"
}

Кто-нибудь может объяснить, что здесь происходит? Почему мой конструктор по умолчанию не вызывается и как я могу получить доступ к объекту, если он не был правильно сконструирован?


person Nick C    schedule 18.08.2011    source источник


Ответы (2)


Насколько я понимаю, в вашем примере не используется блок как таковой, а объявляется foo2 как используемый блоком.

Это делает забавные вещи с обработкой foo2, о которых вы можете узнать больше о здесь.

Надеюсь, это поможет.

person Xav    schedule 18.08.2011
comment
Я попытался сократить пример до минимума, чтобы попытаться понять, что происходит - реальная вещь используется внутри блока. Я уже видел эту статью, но она на самом деле ничего не объясняет. Я вижу, что тогда переменная живет в особом месте и обрабатывается странным образом, но ведь ее все равно нужно сконструировать? - person Nick C; 18.08.2011

Наткнулся на этот старый вопрос. Это была ошибка, которую давно исправили. Теперь __block объекты C++ построены правильно. Если имеется ссылка в блоке и блок копируется, копия кучи конструируется путем перемещения из оригинала или конструируется путем копирования, если она не может быть создана путем перемещения.

person yiding    schedule 29.05.2014