11

我正在使用 NSKeyedUnarchiver 取消归档对象并想使用委托 (NSKeyedUnarchiverDelegate),但我的委托没有被调用。归档和取消归档工作正常,但未调用委托 (unarchiver & unarchiverDidFinish)。有人可以帮忙吗?

我有以下实现:

        class BlobHandler: NSObject , NSKeyedUnarchiverDelegate{

           func load() -> MYOBJECTCLASS{          
              let data:NSData? = getBlob();      
              var mykeyedunarchiver:NSKeyedUnarchiver=NSKeyedUnarchiver(forReadingWithData: data!);
              mykeyedunarchiver.delegate = self;
              let temp=mykeyedunarchiver.decodeObjectForKey("rootobject")
// No delegates are called
                            if temp==nil {
                                blobsexists=false;
                            }else{
                                objectreturn = temp! as! MYOBJECTCLASS;
                                return objectreturn;
                            }
        }

    func save1(myobject:MYOBJECTCLASS){
            let data = NSMutableData()
            var keyedarchiver:NSKeyedArchiver=NSKeyedArchiver(forWritingWithMutableData: data);
            keyedarchiver.encodeObject(maptheme, forKey: "rootobject");

            let bytes = data.bytes;
            let len=data.length; 
            saveblob(bytes);
    }

以下委托(也在我的 Blobhandler 中实现)永远不会被调用:

func unarchiver(unarchiver: NSKeyedUnarchiver, cannotDecodeObjectOfClassName name: String, originalClasses classNames: [String]) -> AnyClass? {
    print("I am in unarchiver !");
    return nil;
}

func unarchiverDidFinish(_ unarchiver: NSKeyedUnarchiver){
    print("I am in unarchiverDidFinish ! ");
}
4

3 回答 3

1

我不知道它是什么,但它在清理和重建项目后工作。我注意到在不同的情况下,构建有时不同步。有时有代码,它在 XCode 中但没有被执行。听起来难以置信,但我猜是真的。XCode 7.2

于 2016-01-18T14:20:07.227 回答
0

我认为第一个函数永远不会被调用,因为您实际上根本没有提供“cannotDecodeObjectOfClassName”,因为您只是尝试取消归档以前归档的数据。您可以尝试此方法(或某些需要类名)来验证您的解决方案(提供一个类不符合 NSCoding):

unarchiver.decodeObjectOfClass(cls: NSCoding.Protocol, forKey: String)

第二个有点棘手。我在类似的情况下尝试过这种方法,结果发现 unarchiverDidFinish 只有在完成完整的取消归档工作并且可能在它被销毁之前才会被调用。例如,我有一个 NSCoding 类,方便启动器就像

required convenience init?(coder aDecoder: NSCoder) {
    let unarchiver = aDecoder as! NSKeyedUnarchiver
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    unarchiver.delegate = appDelegate.uad


    let name = unarchiver.decodeObjectForKey(PropertyKey.nameKey) as! String

    print(321)

    self.init(name: name, photo: photo, rating: rating)
}

uad 是类的一个实例:

class UAD:NSObject, NSKeyedUnarchiverDelegate {
    func unarchiverDidFinish(unarchiver: NSKeyedUnarchiver) {
        print(123)
    }
}

在视图控制器中,加载过程就像

func load() -> [User]? {
    print(1)
    let ret = NSKeyedUnarchiver.unarchiveObjectWithFile(ArchiveURL.path!) as? [User]
    print(2)
    return ret
}

输出如下:

1 321 321 321 321 321 123 2

在加载完一组用户后,unarchiverDidFinish 终于被调用了一次。请注意,这是一个类函数,并创建了一个匿名实例来完成这句话:

NSKeyedUnarchiver.unarchiveObjectWithFile(ArchiveURL.path!) as? [User]

所以我真的相信这个函数只会在它被销毁或一组回调函数完成之前被调用。

我不太确定您是否属于这种情况。您可以尝试使您的 unarchiver 对象成为全局对象并在加载完成后将其销毁,以查看是否调用了此函数。

如果有什么不对的地方请纠正我。

于 2016-01-25T08:08:20.643 回答
0

为了使任何一个正确调用,我们必须unarchiverWillFinish:在完成解码时调用。unarchiverDidFinish:finishDecoding

配置好解码器对象后,要解码对象或数据项,请使用该decodeObjectForKey:方法。完成对键控存档的解码后,您应该finishDecoding在释放 unarchiver 之前调用。

我们通知 NSKeyedUnarchiver 实例的委托,并通过调用此方法对存档执行任何最终操作。根据 Apple 的官方文档,一旦调用此方法,我们的 unarchiver 将无法解码任何进一步的值。如果我们在调用后继续执行任何解码操作,我们将收到以下消息finishDecoding

*** -[NSKeyedUnarchiver decodeObjectForKey:]:解压已经完成,不能再解码

这对于编码对应物也很有意义。

于 2017-01-24T08:25:35.910 回答