ArrayObject implements IteratorAggregate which means it has a method called getIterator() which returns an iterator.
php's foreach loop will automatically retrieve an iterator by calling the getIterator() method for you to retrieve an iterator to iterate over. This is convenient, but you need to get a reference to this iterator in order to call the offsetUnset() method on the iterator itself. The key thing here is you must call the iterators offsetUnset() method, not the ArrayObjects offsetUnset() method.
$ao = new ArrayObject();
$ao[] = 9;
$iter = $ao->getIterator();
foreach ($iter as $k => $v)
$iter->offsetUnset($k); // no error
The underlying ArrayObject that the iterator is iterating over will be mutated, so if you have more than one active iterator at the same time over the same Arrayobject, you'll still encounter the same error.
The rationale for this is likely so that the iterators can be memory efficient and not have to copy the underlying ArrayObject, because a copy is the only simple solution to dealing with the complexity of deciding what the current iterator position should be when things are added to or deleted from the underlying array.