How to check if an object is already destroyed or not? - delphi

I have created an object
I passed it to somewhere else as parameter. Somewhere else has Free the object which out of my control.
At the end my coding, I try to check if the object is valid then destroy it. The Assigned() method returned true (seems it is because the variable storing the object reference address). However, the referenced object ready destroyed and I got an exception.
My question is, how could I check if an object is already destroyed? What else other than Assigned() can check the object still exists or not?
program Project1;
uses System.SysUtils;
type TObj = class
public
Name: string;
end;
var AnObj, AnObj2 : TObj;
begin
try
try
AnObj := TObj.Create;
AnObj.Name := 'Testing';
AnObj2 := AnObj; // AnObj passed to other procedures as param
FreeAndNil(AnObj2); // somewhere else "Free" the object out of my control
// as a result, AnObj is still assigned but the object is destroyed
finally
if Assigned(AnObj) then // AnObj is assigned, HOW COULD I IMPROVE HERE?
FreeAndNil(AnObj); // Exception: Invalid pointer operation
end;
except
on E:Exception do
writeln(E.Message);
end;
readln;
end.

How to check if an object is already destroyed or not?
Short answer is you can't. There is no mechanism that will allow you to to check validity of object under manual memory management.
If you want to track validity for debugging purposes, you can use custom memory manager (like FastMM in full debug mode) that can track all references and will report when you access dangling pointers.
FreeAndNil in combination with Assigned only works when you have single reference to an object. If you have more it falls apart because FreeAndNil can nil only the reference you called it upon. All other references will become dangling pointers and Assigned cannot detect dangling pointers.
In a nutshell, Assigned works only when reference points to valid object instance or contains nil value. Under manual memory management you have to keep track and make sure that your reference always contains valid value if you need to use Assigned.
Using Assigned when you keep single reference to an object
If you have single reference to object, you can use Assigned for lazy initialization pattern where you will create object instance if it is not already created. But you have to make sure that object reference contains nil reference in the first place.
Object references will be automatically initialized to nil only if they are class fields, object instance fields or global variables.
If you don't plan to reuse that object reference once it is released you can use Free for releasing its memory.
If you have reusable reference, where you want to create and release object instance multiple times, you have to use FreeAndNil, or set reference to nil after you call Free. That is the only way you can ensure Assigned will work after object is released. Again, this Assigned/FreeAndNil pattern only works if you keep one and only one reference to that object.
Using Assigned when you keep multiple references to an object
If possible don't ever keep more than one reference to an object instance. If you have scenario where you really must keep multiple references to an object instance you need to implement some mechanism that will ensure you can notify all references that object is no longer valid.
There are several ways to do so:
Using interfaces - their automatic memory management will prevent dangling pointers
Using TComponent as base class - where you can use its notification system to get notifications when object instance is going to be destroyed
Implement your own notification system to manage all references to an object instance
Note: For 2. and 3. you have to manually nil all references to an object when you get notification it will be destroyed. If you don't do that any reference you don't set to nil, will be invalid, dangling reference any using Assigned upon it will fail to work properly.
If you have situation when you passed object as parameter, and some code beyond your control called Free on that object then you are dealing with ownership transfer. You created the object, but then you transferred ownership (responsibility to release object) to some other code. After that you should not use that object reference again (except in some narrow scenarios, when you know for sure that immediate code after transfer is complete will not trigger object release).
You can use object reference you don't own (after you have transferred ownership) only if there is some notification mechanism (as mentioned earlier) that can notify you when object instance is released.
Also you should never, ever free objects you don't own. In your example, even if you can get notified that object is going to be destroyed all you can do is nil the reference that points to it. You should not attempt to release it.

Related

Does ARC set its reference type instance properties to nil before deallocation?

This question occured to me while reading this.
My question is in reference to the image below:
Once john is set to nil, Person instance no longer has any more strong reference and hence will be deallocated. But Apartment has two strong references and one of which is by the property on Person instance that would be soon deallocated. I believe, this strong reference continue to remain after deallocation and goes out of reach by the code.
So, setting unit14A to nil will remove only one strong reference to Apartment instance and it should not be deallocated as there would be one more strong reference due to the above case.
But, as the document says Apartment instance promptly got deallocated. To me, this can only happen if at the time of Person instance deallocation it sets its apartment property to nil, by that removing that strong reference on Apartment instance. But I couldn't find any documentation to verify this.
So, How does the Apartment instance get deallocated? What happened to the strong reference from the Person instance apartment property?
Can someone help me to understand this?
Objective-C objects are reference counted, meaning that for each object, the system keeps track of how many other objects hold a reference to it. This is object's reference count. Two special messages, retain and release, are used to maintain the reference count behind the scene. Once reference count goes down to zero, the system deallocates the object.
ARC provides "magic" to make reference counting work in a declarative way. The compiler knows every strong reference in your code, so when you do this
myStrongRef = nil;
the compiler quietly inserts a call to release in front of the assignment:
[myStrongRef release];
myStrongRef = nil;
To me [deallocation of Apartment] can only happen if at the time of Person instance deallocation it sets its apartment property to nil, by that removing that strong reference on Apartment instance.
Setting a strong reference to nil one way of breaking a strong reference. It is sufficient, but it isn't necessary. The important thing about setting a strong reference to nil is not the act of setting itself, but what happens immediately before it: the instance referred to by the strong reference gets a release message, instructing it to decrement its reference count. That is precisely what ARC does behind the scene for you: it sends the release message to Apartment, without setting Person's reference to nil.
How does the Apartment instance get deallocated? What happened to the strong reference from the Person instance apartment property?
Once strong reference from Person has sent its release message to Apartment, that strong reference disappears. The actual pointer may be set to Apartment's address, but nobody cares about it, because the Person itself is unreachable.
The life of an object depends on it's reference count, not any actual pointer to the object.
Strong reference is a way of speaking, there is no difference between a strong and weak reference, they are just pointers. The difference is that when a strong reference is created the reference count of the object pointed to in incremented and when deleted the reference count is decreased. When an object's reference count would become zero the object is deallocated.
Your intuition is correct. When an object is being deallocated under ARC all the strong references it holds are first relinquished - essentially they are set to nil, but in practice the implementation may differ.
This is also what happens when a method returns, or a block of code containing declarations exits, all the strong references held in local variables are relinquished.
All the details can be found in the Clang documentation.
HTH
Obviously not before deallocation, but during deallocation.
When an object's reference count goes to zero, the deallocation process starts. The object is marked as "being deallocated". At that point, the object will die (unlike Java, where it can be recovered). If an object is marked like this, it cannot be assigned to weak references (they stay nil), or to strong references.
Then dealloc is called, that is the dealloc methods that you have written. After that, strong references are set to nil, reducing their reference counts, then associated objects are removed, and finally the memory for the object is deleted.

Manual reference counting and AutoRelease

In manual memory management on what scenarios you will go for Auto Release
I'd like to be well prepared as I am about to do a project using without ARC
You typically use autorelease when you need to return an object from a method, and relinquish ownership at the same time: upon returning the calling side (not the creating method) should own the object.
If you just relinquish ownership before returning the object (with release), it gets immediately deallocated and the calling side can not use it. If you don't call release, the object has a reference count of +1 from the called function (that instantiated it), which also has no further chance to release after the calling side has claimed ownership.
So, autorelease is like a "deferred release": the object gets sent one release method at a later time (but not before the function that is returning it returns).
Addendum:
The alternative approach is to return objects with an agreed-upon reference count of 1, and rely on the calling side to release it when done.
This is made explicit by adopting a preestablished naming pattern for those methods: In cocoa, they typically contain the words "alloc", "new", "copy" or "mutalbeCopy".
Source: Apple's documentation.

When to use takeUnretainedValue() or takeRetainedValue() to retrieve Unmanaged Objects in Swift?

According to Using Swift with Cocoa and Objective-C you can use takeUnretainedValue() and takeRetainedValue()to tell Swift how to manage the memory of an object for a function like this:
func StringByAddingTwoStrings(CFString!, CFString!) -> Unmanaged<CFString>!
When do I have to use takeUnretainedValue() or takeRetainedValue()?
When I use ARC is it then always takeUnretainedValue()?
You use takeRetainedValue when the unmanaged object has a +1 retain count and you want ARC to take care of releasing the object when you're done. For example, if you call a Core Foundation function with Create or Copy in the name (see Create Rule in the Memory Management Programming Guide for Core Foundation) which returns an unmanaged object for which you are responsible for releasing, you generally use takeRetainedValue so that it is released for you (or, if you don't do this, you have to manually release it yourself with CFRelease or similar function). You use takeUnretainedValue when ownership of the object has not been transferred to you and you therefore do not want ARC releasing the object for you when it falls out of scope.
So, as to when you call takeUnretainedValue vs takeRetainedValue, it simply depends upon what sort of object the called function returns. As a general rule of thumb, if the object was returned from a Core Foundation function with Create or Copy in the name, use takeRetainedValue. Otherwise use takeUnretainedValue.
In terms of what happens if you call the wrong method, if you call takeUnretainedValue when you're passed a +1 object (e.g. an object returned from Core Foundation function with Create or Copy in the name), your app will leak unless you explicitly CFRelease it. You may not immediately notice the occasional leak when running the app, but it can be observed by watching your app's memory usage (e.g. if you profile your app with Instruments). But if you leave these leaks unresolved, your app may eventually receive memory warnings.
On the other hand, if you call takeRetainedValue on an object which has not been retained for you (returned by a function that did not have Create or Copy in its name), the app will likely crash when the object is released. Sometimes this won't manifest itself immediately (not until the last strong reference is resolved), but it will generally result in a catastrophic failure of the app.
So judicious selection of takeUnretainedValue vs takeRetainedValue is very important.
Quoting from NSHipster:
https://nshipster.com/unmanaged/
An Unmanaged instance wraps a CoreFoundation type T, preserving a reference to the underlying object as long as the Unmanaged instance itself is in scope. There are two ways to get a Swift-managed value out of an Unmanaged instance:
takeRetainedValue() returns a Swift-managed reference to the wrapped instance, decrementing the reference count while doing so—use with the return value of a Create Rule function.
takeUnretainedValue() returns a Swift-managed reference to the wrapped instance without decrementing the reference count—use with the return value of a Get Rule function.

Is it possible to implement NSFastEnumeration when using weak references?

I have a collection which maintains weak references to its objects. I'd like it to conform to NSFastEnumeration, but the buffer provided by countByEnumeratingWithState:objects:count: uses unsafe_unretained references. That creates a gap during which a returned reference could become invalid but not zeroed.
That's fine in the general case -- if the collection stuffs its (currently valid but weakly-referenced) object into the buffer and returns it, then the caller will presumably create its own strong reference if needed. But that leaves two problems:
(1) I don't see any guarantee that the for(){} iteration construct itself creates a temporary strong reference to the object, so if the contents of the {x} block changes something outside the collection in a way that causes the object to be released, then it'll have a dangling reference.
(2) There's still a small gap while returning from countByEnumeratingWithState: during which activity on another thread could invalidate the reference. My collection isn't meant to be thread-safe, but it would be nice if it could at least safely store references to objects which could be referenced on another thread, as there's really no way to prevent that in any multi-threaded application.
You can't return a strong reference directly to the caller. The caller won't release it, and the fast enumeration protocol does not guarantee that you will get a chance to release it yourself when the caller is done.
Instead you can retain+autorelease the objects before you store them into the buffer. That would guarantee the objects stay alive while the caller uses them. It may hurt the "fast" part of fast enumeration, but you would still get the "convenient syntax" part. If you add a nil check after you read the weak variable then you can avoid storing nil pointers into the buffer.

Hang on SomeObject.Free. Check if object is already free in FPC?

if if have an object (in my case TJSONData) and I want to free this object the programm flow sometimes hangs at this position. I already have a construct like the following in my code but it seems to not fit the case some times:
if Assigned(MyRecord.MyJSONData) then
begin
MyRecord.MyJSONData.Free;
end;
I can reproduce this behavior in tests if I try to free an object two times. In my program this should normally not happen but now my real question:
Is there a way to check if the object is already free? Or do I need to use also FreeAndNil();?
The Assigned function checks to see if a reference is not nil. It
returns True if not nil, and False if nil.
Obviously when you free the object and do not set reference to nil it will pass on next Assigned check (reference <> nil) and will be attempted to free again. But the reference (pointer) is already dangling (pointing to freed or worse, changed, memory).
Generally you should set your references to nil or better - use FreeAndNil function. This way each time you will want to access the freed object it will be nil and thats your check.
There was a large thread in Delphi forum (the tread that eventually crushed the forum) about FreeAndNil.
Common point was that for 95% of tasks you should not check if an object is alive, you should know it beforehand and architect the program so that you always know and never need those checks.
Some survived or revived links are at http://www.theregister.co.uk/2012/01/16/verity_stob_sons_of_khan_2011/print.html and at https://forums.embarcadero.com/message.jspa?messageID=413796

Resources