If it were possible to efficiently detect "when an object goes out of scope" (actually the question is when the object becomes unreachable) in the general case, then every language would do it. They'd immediately run the destructor and immediate collect the memory, because why not? But it's not possible to efficiently detect when an object becomes unreachable in a general way, or at the very least we don't know how. (I'm not certain if it's actually been proven impossible.)
There's automatic reference counting, which kind of works in some cases. But fails spectacularly in others - a simple doubly-linked list will defeat ARC. In essence, any reasonably complex program that relies on it will probably leak memory, unless the programmer has taken the time to find the spots where the ARC fails and takes care of them manually.
If a reference cycle happens then the only good way to detect that the objects involved have been orphaned is to walk the object graph. Doing that every time an object is deallocated would be horribly inefficient. Also, if you're doing it then there's really no need for the reference counting in the first place, since the object graph walk is perfectly capable of finding all the orphan objects on its own. Much better to just do it periodically, so you can get a whole swath of objects each time you walk the graph.
At which point we've come to to garbage collection, and discovered why that's what all the kids are doing these days.
Reference counting is also not free by itself (ignoring its cycle problems). There's overhead to all the incrementing and decrementing. It can add up in modern systems that toss around objects willy-nilly. Reference counting also adds a ton of additional synchronization points in a multi-threaded scenario.
Yup. I don't think it's any coincidence that the only really prominent place where ARC is being used is iOS.
It's a platform where reference counting was already in place, where you can have a reasonable hope that most the programs are too small and simple to take much of a hit on the overhead, and where memory leaks can't get too far out of hand because the OS reserves the right to kill processes whenever it wants.