美文网首页
Swift踩坑记录

Swift踩坑记录

作者: GoldenChan | 来源:发表于2019-03-05 18:50 被阅读0次

    1.关于NSClassFromString

    通过方法NSClassFromString获取类时,如果来源类是swift的类,则类名的字符串需要拼接为 "项目名称.类名",代码如下

    NSClassFromString("\(Bundle.main.infoDictionary?["CFBundleName"] as! String).\(className)")
    

    2.关于try

    实例代码:

    let mainStoryBoard =UIStoryboard.init(name:"Main", bundle:nil)
    
    let controllerName = "testVCClassName"
    
    do{
    
    var vc=try mainStoryBoard.instantiateViewController(withIdentifier: controllerName)
    
    } catch {
    
    print(error)
    
    }
    

    如果StoryBoard中没有找到指定id名称的UI时,以上代码执行会引起崩溃

    以上通过try执行系统方法instantiateViewController是无法捕获异常的,在改方法声明中可以看到该方法不支持try,因为该方法没有throw操作;以上说明try一般用在会抛出异常的方法执行上面。由此可见,目前swift的捕获异常方式有所局限,系统异常无法都捕获到。

    3.关于链式编程(即使用点语法)和 协议编程

    在oc中如果需要使用点语法,需要通过block来实现,比如下面代码:

    
    //h文件内容
    
    @classTestModel;
    
    @protocolprotocol1;
    
    @protocolprotocol2;
    
    @protocolprotocol1
    
    //设置接收对象的class
    
    - (TestModel *(^)(void)) protocol1Method;
    
    @end
    
    @protocolprotocol2
    
    //设置接收的数组对象的class
    
    - (TestModel *(^)(void)) protocol2Method;
    
    @end
    
    @interfaceTestModel : NSObject
    
    @property(nonatomic,copy) TestModel<protocol1,protocol2> *(^testBlock1)(void) ;
    
    @end
    
    
    
    //m文件内容
    
    @interfaceTestModel()
    
    @end
    
    @implementation TestModel
    
    //protocol1
    
    - (nonnullTestModel *_Nonnull(^)(void))protocol1Method {
    
        return^(){
    
            //operation
    
            return self;
    
        };
    
    }
    
    //protocol2
    
    - (nonnullTestModel *_Nonnull(^)(void))protocol2Method {
    
        return^(){
    
            //operation
    
            return self;
    
        };
    
    }
    
    - (TestModel<protocol1,protocol2> * (^)(void))testBlock1 {
    
        return^(){
    
            //operation
    
            return self;
    
        };
    
    }
    
    @end
    
    

    如果在h文件中声明了block类型的属性,那么在oc中可以这么调用

    
    [[TestModel allock]init].testBlock1().protocol1Method();
    
    

    而这段代码却不能再swift中这么用,可能是swift中没有正确生成该属性的getter方法吧(仅猜测)

    如果将h文件中的block属性的getter方法直接在.h文件中声明,那么swift也可以正常使用点语法了。

    这里我们再提一下面向协议的思想,觉得和链式配合使用挺好的;比如上面的调用如果写成

    
    //protocol2Method无法调用
    
    [[TestModel allock]init].testBlock1().protocol1Method().protocol2Method();
    
    

    则会报错提示没有声明protocol2Method方法,原因是protocol1Method方法返回的对象不支持protocol2协议,所以无法调用;这里就可以控制某些业务逻辑的互斥关系;在他人使用这个对象时可避免使用不当的问题。

    延伸一下,关于函数式编程(就是讲block当做方法的参数传递),同样放在此配合使用也可以大大简化代码的可阅读性,将代码业务逻辑模块化;具体思想可参考masonry库的编程思想。

    相关文章

      网友评论

          本文标题:Swift踩坑记录

          本文链接:https://www.haomeiwen.com/subject/kznouqtx.html