Arhn - архитектура программирования

захваченное «я» высвобождается внутри dispatch_async

Я испытываю ошибку EXC_BAD_ACCESS внутри своего приложения в блоке, который, насколько я понимаю, должен фактически фиксировать все, что связано с этим, что делает невозможным его выпуск внутри блока. (ARC включен)

Вот мой код:

- (void)_perform_async_onqueue:(void (^)(void))task {
    dispatch_async(self.workerQueue, task);
}

- (void)cancel {
    [self _perform_async_onqueue:^{
        // operation is strongly retained by self.
        // operation is also retained by an operation queue.
        // within `cancel` the operation is released from the operation queue
        [self.operation cancel];
    }
}];

Это падает внутри [self.operation cancel]. self.operation является подклассом NSOperation. Метод операции cancel в деталях:

- (void)cancel {
    [self willChangeValueForKey:@"isCancelled"];
    _cancelled = YES;
    [self didChangeValueForKey:@"isCancelled"];
    [self willChangeValueForKey:@"isFinished"];
    [self willChangeValueForKey:@"isExecuting"];
    _finished = YES;
    _executing = NO;
    [self didChangeValueForKey:@"isExecuting"];
    [self didChangeValueForKey:@"isFinished"]; // CRASH (debugger lists `self` [= the operation] as `nil` in this line
}

Насколько я понимаю, первый self должен оставаться внутри отправленного блока. Поскольку self имеет ссылку strong на operation, она также должна находиться в памяти до конца выполнения блока. Как это может привести к сбою EXC_BAD_ACCESS?


Ответы:


1

РЕДАКТИРОВАТЬ :

Не реализуйте метод отмены в вашем подклассе NSOperation. Просто позвони :

[self.operation cancel];

Хороший учебник здесь

22.09.2015
  • К сожалению, это не решает проблему. Я был почти уверен, что это какое-то состояние гонки, но хотел понять, почему... кажется, что это не так... теперь это меня еще больше сбивает с толку. :/ 22.09.2015
  • ммх... что происходит с NSLock? NSLock *myLock; [блокировка myLock]; [сам будетChangeValueForKey: @"someKey"]; какой-то ключ = что-то еще; [сам сделалChangeValueForKey: @"someKey"]; [разблокировка myLock]; 22.09.2015
  • это приводит к той же проблеме :( 22.09.2015
  • Становится ли 'self' 'nil' сразу после [self didChangeValueForKey:@isExecuting]; ? Не раньше, чем ? 22.09.2015
  • Насколько я понимаю, при выполнении этой строки он получит nil. Я не могу сломаться там, так как это происходит только время от времени. Если бы она стала nil перед строкой, эта строка не должна ничего делать, так как сообщение было бы отправлено на nil, верно? 22.09.2015
  • Ждать. Я прочитал эти спецификации о NSOperation, он совместим с KVO, и вам не нужно обновлять флаги: developer.apple.com/library/ios/documentation/Cocoa/Reference/. Посмотрите на команду отмены. Не реализуйте это. Просто создайте подкласс NSOperation и вызовите метод отмены. 22.09.2015
  • Это асинхронная операция, поэтому я думаю, что должен сам запускать уведомления KVO, иначе очередь операций не удаляет операцию из очереди. Я использовал AFNetworking в качестве примера при реализации операции. 22.09.2015

  • 2

    Методы не имеют сильных ссылок на себя. Если self освобождается во время вызова метода, вы предоставлены сами себе. (Вот почему вы получаете предупреждение, если вызываете метод для слабого объекта, потому что объект может исчезнуть во время выполнения метода).

    Вы можете назначить SomeClass* самостоятельно = self; и это будет поддерживать жизнь до конца метода.

    Вы также можете реализовать свой собственный Dealloc (который просто автоматически вызывает [super Dealloc]) и установить точку останова, чтобы узнать, когда именно освобождается self, чтобы лучше понять ситуацию.

    22.09.2015
  • Это тоже не помогает. Кроме того, в моем понимании, не должно иметь никакого значения, оставлю ли я сильный self или сильный myself в своем блоке. 22.09.2015

  • 3

    Я нашел проблему:

    Оказывается, описанное поведение работает совершенно нормально. Проблема в том, что NSOperation, который используется здесь, является пользовательской асинхронной операцией, в которой отмена реализована неправильным образом: если вы отмените операцию до, она была запущена NSOperationQueue, то очередь операций перевыпустится. операция. Это причина того, что операция освобождается, даже если все еще существует сильная ссылка, которая должна ее удерживать.

    Я пойду файл rdar для этого.

    22.09.2015
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..