微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ios – 重命名并重写为Swift后对象解码崩溃

由于我们已经重命名了(Bestemming – > Place)类并将其从 Objective-c重写为Swift,因此一些用户会遇到崩溃.我们正在尝试使用NSCoding原则从NSUserDefaults加载对象.

碰撞:

Thread : Crashed: com.apple.main-thread
0  Flitsmeister                   0x10018b720 specialized Place.init(coder : NSCoder) -> Place? (Place.swift)
1  Flitsmeister                   0x10018a6f4 @objc Place.init(coder : NSCoder) -> Place? (Place.swift)
2  Foundation                     0x1839ab92c _decodeObjectBinary + 2276
3  Foundation                     0x1839aaf90 _decodeObject + 304
4  Foundation                     0x1839aa124 +[NSKeyedUnarchiver unarchiveObjectWithData:] + 92
5  Flitsmeister                   0x100103fa0 +[SharedUserDefaultsManager WorkPlace] (SharedUserDefaultsManager.m:72)
6  Flitsmeister                   0x100090830 -[InvoerBestemmingTableViewController viewWillAppear:] (InvoerBestemmingTableViewController.m:106)
7  UIKit                          0x187d8074c -[UIViewController _setViewAppearState:isAnimating:] + 628
8  UIKit                          0x187d804c0 -[UIViewController __viewWillAppear:] + 156
9  UIKit                          0x187e27130 -[UINavigationController _startTransition:fromViewController:toViewController:] + 760
10 UIKit                          0x187e26a6c -[UINavigationController _startDeferredTransitionIfNeeded:] + 868
11 UIKit                          0x187e26694 -[UINavigationController __viewWillLayoutSubviews] + 60
12 UIKit                          0x187e265fc -[UILayoutContainerView layoutSubviews] + 208
13 UIKit                          0x187d63778 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 656
14 QuartzCore                     0x185772b2c -[CALayer layoutSublayers] + 148
15 QuartzCore                     0x18576d738 CA::Layer::layout_if_needed(CA::Transaction*) + 292
16 QuartzCore                     0x18576d5f8 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
17 QuartzCore                     0x18576cc94 CA::Context::commit_transaction(CA::Transaction*) + 252
18 QuartzCore                     0x18576c9dc CA::Transaction::commit() + 512
19 UIKit                          0x187d59c78 _afterCACommitHandler + 180
20 CoreFoundation                 0x18302c588 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
21 CoreFoundation                 0x18302a32c __CFRunLoopDoObservers + 372

班级:

@objc(Place)
class Place : NSObject,NSCoding,CustomDebugStringConvertible
{
    let name: String

    let location: CLLocation
    var lastUsed: NSDate?

    var type: PlaceType

    var address: String?
    //MARK: - NSCoding protocol

    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(name,forKey: "name")
        aCoder.encodeObject(address,forKey: "address")
        aCoder.encodeInt(type.rawValue,forKey: "type")
        aCoder.encodeObject(location,forKey: "location")
        aCoder.encodeObject(lastUsed,forKey: "lastUsed")
    }

    required init?(coder aDecoder: NSCoder) {


        if let locatieNaam : String = aDecoder.decodeObjectForKey("locatieNaam") as? String {
            //This is the OLD object
            name = locatieNaam

            let nullableLocation : CLLocation? = aDecoder.decodeObjectForKey("locatie") as? CLLocation
            if let notnulllablelocation : CLLocation = nullableLocation {
                location = notnulllablelocation
            } else {
                location = CLLocation.init(latitude: 0,longitude: 0) //Not possible
            }
            lastUsed = aDecoder.decodeObjectForKey("lastUsed") as? NSDate

            if aDecoder.decodeBoolForKey("isThuis") {
                type = .Home
            } else if aDecoder.decodeBoolForKey("isWerk") {
                type = .Work
            } else if aDecoder.decodeBoolForKey("isFavoriet") {
                type = .Favoriet
            } else {
                type = .Other
            }

            address = nil
        }
        else {
            name = aDecoder.decodeObjectForKey("name") as! String
            let nullableLocation : CLLocation? = aDecoder.decodeObjectForKey("location") as? CLLocation

            if let notnullableLocation : CLLocation = nullableLocation {
                location = notnullableLocation
            } else {
                location = CLLocation.init(latitude: 0,longitude: 0) //Not possible
            }

            lastUsed = aDecoder.decodeObjectForKey("lastUsed") as? NSDate
            type = PlaceType.init(rawValue: aDecoder.decodeInt32ForKey("type"))!
            address = aDecoder.decodeObjectForKey("address") as? String
        }
    }
}

从NSUserDefaults阅读:

+ (Place*)WorkPlace;
{
    @try {
        NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:kSharedUserDefaults];

        NSData *result = [mySharedDefaults objectForKey:kWerkBestemming];
        if(result == NULL)
            return nil;

        [NSKeyedUnarchiver setClass:[Place class] forClassName:@"Bestemming"];
        [NSKeyedUnarchiver setClass:[Place class] forClassName:@"BestemmingBase"];

        Place *place = [NSKeyedUnarchiver unarchiveObjectWithData:result];
        if(place != nil) {
            place.type = PlaceTypeWork; //Needed because the old Bestemming class didnt saved the boolean isWerk
        }
        return place;
    }
    @catch (NSException *exception) {
        return nil;
    }
}

崩溃日志说它在第0行崩溃,这是注释所以我认为它在init方法中崩溃,我认为它与一个null为空但不能为null的对象有关.

我尝试过的:

>尝试在SharedUserDefaultsManager中捕获
>对非空缺的额外检查

对于应用程序崩溃的用户,我可以使用从NSUserDefaults中删除对象.只有我知道它何时发生.

解决方法

认为这是处理NSCoding init方法的更好方法,如果变量不是您所期望的,则返回nil:
required convenience init?(coder decoder: NSCoder) {
    guard let title = decoder.decodeObjectForKey("title") as? String,let author = decoder.decodeObjectForKey("author") as? String,let categories = decoder.decodeObjectForKey("categories") as? [String]
        else { return nil }

    self.init(
        title: title,author: author,pageCount: decoder.decodeIntegerForKey("pageCount"),categories: categories,available: decoder.decodeBoolForKey("available")
    )
}

来自NSHipster:http://nshipster.com/nscoding/

现在让我们看看新版本是如何运作的.

编辑:它奏效了!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple 最新软件的错误和性能问题。
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只有5%的概率会遇到选择运营商界面且部分必须连接到iTunes才可以激活
一般在接外包的时候, 通常第三方需要安装你的app进行测试(这时候你的app肯定是还没传到app store之前)。
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应用变灰了。那么接下来我们看一下Flutter是如何实现的。Flutter中实现整个App变为灰色在Flutter中实现整个App变为灰色是非常简单的,只需要在最外层的控件上包裹ColorFiltered,用法如下:ColorFiltered(颜色过滤器)看名字就知道是增加颜色滤镜效果的,ColorFiltered( colorFilter:ColorFilter.mode(Colors.grey, BlendMode.
flutter升级/版本切换
(1)在C++11标准时,open函数的文件路径可以传char指针也可以传string指针,而在C++98标准,open函数的文件路径只能传char指针;(2)open函数的第二个参数是打开文件的模式,从函数定义可以看出,如果调用open函数时省略mode模式参数,则默认按照可读可写(ios_base:in | ios_base::out)的方式打开;(3)打开文件时的mode的模式是从内存的角度来定义的,比如:in表示可读,就是从文件读数据往内存读写;out表示可写,就是把内存数据写到文件中;
文章目录方法一:分别将图片和文字置灰UIImage转成灰度图UIColor转成灰度颜色方法二:给App整体添加灰色滤镜参考App页面置灰,本质是将彩色图像转换为灰度图像,本文提供两种方法实现,一种是App整体置灰,一种是单个页面置灰,可结合具体的业务场景使用。方法一:分别将图片和文字置灰一般情况下,App页面的颜色深度是24bit,也就是RGB各8bit;如果算上Alpha通道的话就是32bit,RGBA(或者ARGB)各8bit。灰度图像的颜色深度是8bit,这8bit表示的颜色不是彩色,而是256
领导让调研下黑(灰)白化实现方案,自己调研了两天,根据网上资料,做下记录只是学习过程中的记录,还是写作者牛逼