如何使用NSKeyedUnarchiver的代理?

时间:2016-01-16 07:30:56

标签: swift delegates nskeyedunarchiver

我正在使用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 ! ");
}

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分: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对象全局化并在加载完成后销毁它以查看是否调用此函数。

如果不对,请纠正我。

答案 2 :(得分:0)

要正确调用unarchiverWillFinish:unarchiverDidFinish:,我们必须在完成解码时调用finishDecoding

  

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

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

  

*** - [NSKeyedUnarchiver decodeObjectForKey:]:unarchive已经完成,无法解码更多

对于编码对应物也是有意义的。