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 FarmerOwners 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
NSArchivers and NSKeyedArchivers 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.