This happens because setClass cannot add instance variables to an object that has already been created. setClass is only safe if the new class does not have additional ivars. This is not specific to Swift, regular ObjC is limited in the same way.
A related problem is that setClass will not call init again, so even if you did get space for your ivars (which you only would out of pure chance), they wouldn’t be initialized.
You cause undefined behaviour by setting your object’s class to a larger type, and you read/write whatever happens to be next in memory at that location. A read for a double will only crash if your object was right at the end of a virtual memory page and the next page is unmapped. A write may crash for the same reason, and may eventually cause a crash if you write a double to a location that your program assumes to be a pointer elsewhere, and you eventually hit that elsewhere. Pointers typically look like near-zero double values, so it’s likely to be what you’re seeing.
A read or write of a reference type is likely to crash right away due to compiler-inserted retain count calls that can’t deal with object pointers that turn out to not be object pointers.
It is “safe” to use setClass to change the type of your object to a superclass, or to a subclass that only adds and overrides methods or properties without creating new ivars.