我有一个objective-c类,它包含一个指向另一个类的指针。我想通过NSCoder存档这个类的一个实例:
@interface Barn
{
int m_numHorses;
// Barn does not allocate this instance, it just points to it.
Farmer* m_pFarmer;
}
@end
...
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeInt:m_numHorses forKey:@"numHorses"];
[encoder encode?:m_pFarmer forKey:@"pFarmer"];
}
- (void) setPointer:(Farmer*)pFarmer
{
m_pFarmer = pFarmer;
}如何归档m_pFarmer指针?这对我来说没有意义,因为它只是一个地址,我不知道NSCoder可以为你序列化到磁盘上的什么东西,以便它知道如何在以后反序列化时恢复链接?
发布于 2009-05-17 23:50:18
您不能直接对指针进行编码,因为当您解压对象时,指针的值将完全不同。我是说,你可以把它存储在
encodeValueOfObjCType:@encode(id) at:&m_pFarmer 但是不能保证反序列化的指针会指向反序列化的farmer;事实上,它很可能不会。
如果Barn不拥有Farmer,那么Barn不应该在反序列化时重新创建它;您最终会得到一个与原始Farmer不分离的新a。那么,您需要的是找到原始Farmer的反序列化实例的方法,并用另一个实例替换Barn的Farmer实例。
有人拥有Farmer,对吧?因此,Barn需要有一个findMyFarmer方法,该方法遍历所有的FarmerOwner并找到它应该使用的原始实例。(也许可以通过比较Farmer上的farmerID ivar?)完成后,您可以在Barn上实现-[NSObject awakeAfterUsingCoder:(NSCoder *)]来触发农民替换例程。
希望这是有意义的。查看关于存档和序列化的documentation,特别是关于编码和解码对象的页面,以了解有关动态替换对象的更多信息。
更新
NSArchiver和NSKeyedArchiver支持 archiving的思想(通过encodeConditionalObject:),即只有当归档中的其他对象已经添加了对象时,才将该对象添加到归档中。文档中写道:“通常,条件对象用于编码对objects的弱引用或非保留引用。”。因此,如果您的Farmer已经存档,那么您可能想要添加它,但是如果您只对Barn进行编码,而没有任何farmer,那么您就不会想要这样做。
一定要查看上面提到的文档。
发布于 2009-05-17 21:10:15
您应该使用encodeObject:并在Farmer类中实现NSCoding,这样就可以递归地调用它。
发布于 2009-05-18 00:48:28
您应该先阅读BJ指向的文档。
序列化库足够智能,可以检测同一对象的重复,并且只会对其进行一次编码。因此,一般来说,如果以后需要这个对象,您应该对它进行编码。序列化库甚至可以处理图形循环。您不需要担心这些事情,也不应该主动尝试猜测其他对象将如何处理此对象。ObjC没有C++通常需要的那种强对象所有权概念。引用计数内存管理不需要它,也不应该重新创建它。
说到引用计数,你的意思是不在你的二传手中保留Farmer吗?这是因为Barn已经在留住Farmer了吗?或者这是垃圾回收代码?或者这是一次无意的保留不足?当你反序列化这个东西时,如果你实际上没有保留它,这肯定会导致崩溃。
https://stackoverflow.com/questions/875459
复制相似问题