If you write self.fullName = newValue it means you're calling the setter of the fullName property. But since you're already in the setter of fullName what happens is the setter will call itself, recursively, and this will create an infinite loop that ends only once the stack memory is exhausted.
What you need to do is assign the value to another property. Something that would make sense here is to split the name in two and store the parts in prefix and name. Something like this:
set {
let parts = newValue.split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)
self.prefix = parts.count == 2 ? String(parts[0]) : nil
self.name = String(parts.last!)
}
Now the setter is no longer calling itself and the program won't crash. Also, the getter will rebuild the original string from prefix and name whenever it gets called.
By the way, fullName here is a computed property since you specify the getter and setter. A computed property has no storage, all the getter and setter can do is read and write data elsewhere. In this case, the actual data belongs to the prefix and name properties. Because you aren't specifying a getter and a setter for prefix and name, they are stored properties and they actually contain data.