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库的编程思想。
网友评论