Объект iOS target-c: когда использовать релиз, а когда - нет - PullRequest
0 голосов
/ 13 сентября 2018

Я нахожусь под iOS и разрабатываю с Delphi Tokyo, и это мой код:

      aUIImage := TUIImage.Wrap(TUIImage.alloc.initWithCGImage(aCGImageRef));
      try

        aData := TNSData.Wrap(UIImageJPEGRepresentation((aUIImage as ILocalObject).GetObjectID, cWin_DefaultJPGCompressionRate / 100));
        try
          aWorkPicStream.WriteBuffer(aData.bytes^, aData.length);
        finally
          aData.release; // << this make my code will crash (later not now)
        end;

      finally
        aUIImage.release;
      end;

После выполнения кода до того, как я чуть позже выполнил эту ошибку:

myproj  [E][W][I][D][V] Error => Access violation at address 0000000184D4891C, accessing address 0000000107FD286C
At address: $0000000184D4891C (objc_msgSend + 28)

Call stack:
myproj                    $0000000103E00548 Grijjy.Errorreporting.TgoExceptionReporter.GlobalGetExceptionStackInfo(TExceptionRecord*) + 196
myproj                    $00000001030DF0EC Sysutils.Exception.RaisingException(TExceptionRecord*) + 88
myproj                    $0000000103116164 Sysutils.RaiseExceptObject(TExceptionRecord*) + 84
myproj                    $00000001030BB498 _RaiseAtExcept(TObject*, Pointer) + 128
myproj                    $00000001030DD900 Internal.Excutils.SignalConverter(NativeUInt, NativeUInt, NativeUInt) + 68
libobjc.A.dylib           $0000000184D5213C <redacted> + 844
CoreFoundation            $0000000185A40AAC _CFAutoreleasePoolPop + 28
Foundation                $00000001864FB960 <redacted> + 148
myproj                    $00000001031B426C Classes.ThreadProc(Classes.TThread*) + 948
myproj                    $00000

Если я прокомментирую строку aData.release;, я не увижу никакой ошибки.

Почему? Как узнать, когда мы должны вызывать release, а когда не должны вызывать release?

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Помимо вышеуказанных правил, для общей отладки вы можете запустить статический анализ вашей цели - "Cmnd + Shift + B (Build)".Это дало бы некоторое представление о возможных утечках памяти.(Примечание. В некоторых случаях это может означать возможную утечку памяти для объекта, но объект может быть освобожден в другом месте кода. Это зависит от вашей реализации)

0 голосов
/ 13 сентября 2018

Правила ARC для iOS довольно просты, как описано в Основные правила Apple по управлению памятью .

Методы, чье имя начинается с alloc, new, copy или mutableCopy, не требуют вызовов на retain. Напротив, если вы назовете это, вы создадите утечку памяти, потому что будет retain слишком много. Но они требуют release или autorelease. Эти экземпляры объектов являются теми, которые вы создали, и в Objective-C они автоматически сохраняются при создании.

aUIImage построен с использованием alloc, вы являетесь его владельцем и несете ответственность за его выпуск с помощью release. С другой стороны, у вас нет aData, и он будет обрабатываться системой.

Еще одна вещь, которую нужно иметь в виду, это то, что для объектов, которыми вы не владеете, вам может потребоваться вызвать как retain, так и release, чтобы сохранить экземпляр объекта живым, пока вы его используете. Поскольку полученный объект обычно гарантированно остается действительным в методе, в котором он был получен, вам не нужно вызывать retain и release при aData в вашем коде.


Метод retainCount возвращает текущий счетчик ссылок экземпляра объекта Objective-C. Это число является чисто информативным и не имеет значения для отладки под iOS или macOS, однако оно достаточно хорошо, чтобы показать взаимодействие между Objective-C и управлением памятью Delphi, и иногда может быть полезным.

Из документации Apple о retainCount :

retainCount - Не используйте этот метод

Этот метод не имеет значения при отладке проблем управления памятью. Поскольку любое количество объектов каркаса могло сохранить объект в Для того, чтобы держать ссылки на него, в то же время авторелиз пулы могут содержать любое количество отложенных выпусков на объекте, маловероятно, что вы сможете получить полезную информацию с помощью этого метода.

...