You can't directly encode a pointer, because when you unarchive the objects, the pointer's value is going to be entirely different. I mean, you could store it with
encodeValueOfObjCType:@encode(id) at:&m_pFarmer
but there's no guarantee that the deserialized pointer will point to the deserialized farmer; in fact, it's very very likely that it won't.
If Barn
doesn't own the Farmer
, then Barn
shouldn't recreate it on deserialization; you'll end up with a new Farmer
that's not separate from the original one. What you need, then, is a way to find the deserialized instance of the original Farmer, and replace Barn's instance of the Farmer with the other one.
Somebody owns the Farmer
, right? So Barn
needs to have a findMyFarmer
method, which looks through all the FarmerOwner
s and finds the original instance it should be using. (Maybe by comparing a farmerID
ivar on the Farmer
?) Once that's done, you can implement -[NSObject awakeAfterUsingCoder:(NSCoder *)]
on the Barn
to trigger a farmer-replacement routine.
Hope that makes sense. Look at the documentation on Archiving and Serialization, especially the page on Encoding and Decoding Objects to see more about replacing objects on the fly.
Update
NSArchiver
s and NSKeyedArchiver
s support the idea of conditional archiving, (via encodeConditionalObject:
) in which the object is added to the archive only if some other object in the archive has already added it. The documentation says "Typically, conditional objects are used to encode weak, or non-retained, references to objects.". So if your Farmer
is being archived already, then you'd want to add it, but if you're only encoding your Barn
without any farmer, then you wouldn't want to.
Definitely check out the documentation referenced above.