问题描述
我在iOS下,并且在delphi Tokyo开发,这是我的代码:
I m under iOS and I m developping with delphi Tokyo, and this is my code :
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;
在执行代码之前,我在稍后执行此错误:
After executing the code before I have a little later in the execution this error :
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;
行,那么我将不会遇到任何错误。
If i comment the line aData.release;
then i will not meet any error.
为什么呢如何知道何时必须调用发布以及何时不调用发布?
Why ? How to know when we must call release and when we must not call release ?
推荐答案
iOS的ARC规则非常简单,如下所述在中。
ARC rules for iOS are rather simple as explained in Apple's Basic Memory Management Rules.
名称以 alloc
, new
, 副本
或 mutableCopy
不需要调用保留
。相反,如果调用它,则会造成内存泄漏,因为保留
太多。但是它们确实需要释放
或自动释放
。这些对象实例是您创建的对象实例,在Objective-C下,它们在构造时会自动保留。
Methods whose name begins with alloc
, new
, copy
, or mutableCopy
don't require calls to retain
. On the contrary, if you call it you will create a memory leak because there will be one retain
too many. But they do require release
or autorelease
. Those object instances are the ones you have created, and under Objective-C they are automatically retained when constructed.
aUIImage
是使用 alloc
构造的,您拥有它,并负责使用 release
释放它。另一方面,您不拥有 aData
,它将由系统处理。
aUIImage
is constructed using alloc
, you own it and you are responsible for releasing it with release
. On the other hand you don't own aData
and it will be handled by the system.
另一件事请记住,对于您不拥有的对象,可能需要同时调用 retain
和 release
来保持只要您正在使用该对象实例,该实例就仍然有效。由于通常可以保证接收到的对象在接收方法中仍然有效,因此您不必调用 retain
和 release
在代码中的 aData
之后。
Another thing to keep in mind is that for objects you don't own, you may need to call both retain
and release
to keep the object instance alive as long as you are using it. As received object is normally guaranteed to remain valid within the method it was received in, you don't have to call retain
and release
upon aData
in your code.
The retainCount
方法返回Objective-C对象实例的当前引用计数。这个数字纯粹是有用的,在iOS或macOS下没有调试价值,但是它足以显示Objective-C和Delphi内存管理之间的交互作用,有时可能会有所帮助。
The retainCount
method returns the current reference count of the Objective-C object instance. This number is purely informative and has no debugging value under iOS or macOS, however it is good enough to show the interaction between Objective-C and Delphi memory management and can be helpful at times.
来自Apple文档,有关:
From the Apple documentation about retainCount:
此方法在调试内存管理问题时没有任何价值。
因为任意数量的框架对象都可能以
的顺序保留了对象,以保留对其的引用,而自动释放
池可能同时保留了对象上任意数量的延迟释放,
不太可能从这种方法中获得有用的信息。
This method is of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method.
这篇关于iOS Objective-C对象:何时使用发布以及何时不使用发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!