I have an object in Realm. I would like to retrieve that object and then work with an unmanaged version of that object. Unfortunately, it doesn't seem like Realm for iOS has any good copy options, so I tried to followed the "detachable" workaround by "anlaital" outlined in issue #3381.
My code is as follows:

This works for the most part. When on a property that is a list and has values, detachable.detached() does return the expect list copy. Unfortunately, detached.setValue(detachable.detached(), forKey: property.name) does not set the value for any Lists my object has.

Any thoughts on how I can properly assign my "detached"/unmanaged list to my object?
Realm lists don't support reassignment. This is why we recommend that they be declared as let rather than var; anything you can do with a var list you can't do with a let list is considered erroneous behavior.
Alright; as an alternative, is there a way to append to a list by key?
For what it's worth, I've had success with this approach:

I'm appending to lists (reference grabbed via getValue:forKey: ). The unfortunate part is I must be quite verbose when checking list types (note the as? List<Int>, as? List<String, and so on).
I'm glad you figured out something that worked, and I hope others can benefit from your approach! Feel free to open new tickets if you have additional questions.
@austinzheng You comment:
Realm lists don't support reassignment
Seems to contradict the documentation:
You can access and assign List properties as usual:
Am I missing it in the docs, or is it simply a little vague?
The documentation is either unclear or wrong. I think the original intent was to say you can modify the elements inside a List, including assigning new objects to a particular index, rather than assigning a new List instance altogether. I'll update it, thanks for bringing it to our attention.
@allenhumphreys Comment on my other issue (#5469) gave me a magnificent idea.
Instead of having the messy casting for lists like I do in post 4 (which incidentally crashes for objects), because this is a detached/unmanaged object, I should be able to safely do setValueForKey for lists.
I tested this and it seemed to work, but I would like to hear your thoughts @austinzheng.
Do you think it is safe to set/assign a list in this manner on the premise that everything is unmanaged?

If it's unmanaged I don't see why it would be problematic. Does it work?
Indeed it does. I ran a few test cases and they all seemed to work beautifully. However, I do look forward to using this in a project and, effectively, testing it more broadly.
I appreciate your input.
Thank you @Alarson93 this was much helpful :)
This solution works indeed.
If anyone needs the code from @Alarson93, especially when dealing with #3381 (which "accepted" is broken since it doesn't support List
import Realm
import RealmSwift
public extension Object {
public func detached() -> Self {
let detached = type(of: self).init()
for property in objectSchema.properties {
guard let value = value(forKey: property.name) else { continue }
if property.isArray == true || property.type == .object {
// Realm List and Realm Objects
let detachable = value as? Object
detached.setValue(detachable?.detached(), forKey: property.name)
} else {
// Primitives
detached.setValue(value, forKey: property.name)
}
}
return detached
}
}
public extension Sequence where Iterator.Element : Object {
public func detached() -> [Element] {
return self.map({ $0.detached() })
}
}
public extension List {
public func detached() -> List<Element> {
let result = List<Element>()
self.forEach { element in
if let element = element as? Object {
// Realm Objects
result.append(element.detached() as! Element)
} else {
// Primitives
result.append(element)
}
}
return result
}
}
I actually have a slightly newer version of this.
```import RealmSwift
protocol DetachableObject: AnyObject {
func detached() -> Self
}
extension Object: DetachableObject {
func detached() -> Self {
let detached = type(of: self).init()
for property in objectSchema.properties {
guard let value = value(forKey: property.name) else { continue }
if property.isArray == true {
//Realm List property support
let detachable = value as? DetachableObject
detached.setValue(detachable?.detached(), forKey: property.name)
} else if property.type == .object {
//Realm Object property support
let detachable = value as? DetachableObject
detached.setValue(detachable?.detached(), forKey: property.name)
} else {
detached.setValue(value, forKey: property.name)
}
}
return detached
}
}
extension List: DetachableObject {
func detached() -> List
let result = List
forEach {
if let detachable = $0 as? DetachableObject {
let detached = detachable.detached() as! Element
result.append(detached)
} else {
result.append($0) //Primtives are pass by value; don't need to recreate
}
}
return result
}
func toArray() -> [Element] {
return Array(self.detached())
}
}
extension Results {
func toArray() -> [Element] {
let result = List
forEach {
result.append($0)
}
return Array(result.detached())
}
}
Hi, can someone translate @Alarson93's solution in Objective C.
Good solution, almost all our realm related crashes are gone, except that now our app crash Object has been deleted or invalidated is pointing to the detaching process for the value getter:
guard let value = value(forKey: property.name) else { continue }
@loilee I am also getting this kind of crash. Have you reported it or solved it?
@Alarson93 ,
Your solution doesn't work if A's child object has A as a child.
@winstondu
Can you provide a simple example? (Pseudo-code is fine)
Also - what happens? Does it simply not map, does it crash, etc?
Most helpful comment
I actually have a slightly newer version of this.
```import RealmSwift
protocol DetachableObject: AnyObject {
func detached() -> Self
}
extension Object: DetachableObject {
}
extension List: DetachableObject { {()
func detached() -> List
let result = List
}
extension Results {()
func toArray() -> [Element] {
let result = List
}