zoukankan      html  css  js  c++  java
  • Swift 与 Objc Exception

    一、背景

      Swift具备完善的Error handle机制,对于纯Swift下面的Error,在编码的时候能够正确处理。

      在使用try? 处理抛出Error的方法的时候,会忽略Error,直接返回nil

    二、Swift 与 Objc下面的Exception

      下面的代码是经常遇到的一种场景,Swift序列化

        private func serialize(message: Message, pretty: Bool) -> String? {
            var result: String?
            do {
                let data = try JSONSerialization.data(withJSONObject: message, options: pretty ? .prettyPrinted : JSONSerialization.WritingOptions(rawValue: 0))
                result = String(data: data, encoding: .utf8)
            } catch let error {
                log(error)
            }
            return result
        }
    

      虽然这个序列化的API有标注throws标记,但是抛出的异常是objc的异常,这个swift中的try catch是catch不住的

        /* Generate JSON data from a Foundation object.
      If the object will not produce valid JSON then an exception will be thrown.
      Setting the NSJSONWritingPrettyPrinted option will generate JSON with whitespace designed to make the output more readable.
      If that option is not set, the most compact possible JSON will be generated.
      If an error occurs, the error parameter will be set and the return value will be nil.

      The resulting data is a encoded in UTF-8. */ open class func data(withJSONObject obj: Any, options opt: JSONSerialization.WritingOptions = []) throws -> Data

      如果传递一个非可序列化的对象,那么将会导致下面的Crash

      三、规避方案

      Swift部分的方法存在throws的时候,需要特别注意是不是抛出的objc异常,如果是,那么需要特别处理,针对本例子当中,可以采用下面的方法判断一个对象是否可以序列化

        /* Returns YES if the given object can be converted to JSON data, NO otherwise. The object must have the following properties:
            - Top level object is an NSArray or NSDictionary
            - All objects are NSString, NSNumber, NSArray, NSDictionary, or NSNull
            - All dictionary keys are NSStrings
            - NSNumbers are not NaN or infinity
         Other rules may apply. Calling this method or attempting a conversion are the definitive ways to tell if a given object can be converted to JSON data.
         */
        open class func isValidJSONObject(_ obj: Any) -> Bool
    

      修改之后的代码

            guard JSONSerialization.isValidJSONObject(message) else {
                log("(message) json object not valid")
                return nil
            }
    

      除此之外,stackoverflow上面还提供一种方案,OC下面封装一个方法,这个方法内部catch所有NSException的异常信息,然后作为结果返回出来

      比如:https://stackoverflow.com/questions/32758811/catching-nsexception-in-swift

    NSError *tryCatch(void(^tryBlock)(), NSError *(^convertNSException)(NSException *))
    {
        NSError *error = nil;
        @try {
            tryBlock();
        }
        @catch (NSException *exception) {
            error = convertNSException(exception);
        }
        @finally {
            return error;
        }
    }
    

      

      

  • 相关阅读:
    MySQL8.0.x免安装配置
    Java中锁的实现与内存语义
    并发中的volatile
    「LOJ #2163」「POI2011」Tree Rotations
    「CodeChef REBXOR」Nikitosh and xor
    「Codeforces 429D」Destiny
    「Luogu P2042」「NOI2005」维护数列
    「SPOJ SEQ」 Recursive Sequence
    「GCJ 2008 Round 1A C」numbers
    「LOJ #6016」崂山白花蛇草水
  • 原文地址:https://www.cnblogs.com/doudouyoutang/p/15006862.html
Copyright © 2011-2022 走看看