美文网首页
iOS Swift开发遇到的问题汇总

iOS Swift开发遇到的问题汇总

作者: Lee坚武 | 来源:发表于2022-02-18 18:09 被阅读0次

    本人亲测有效!绝对可靠!更多方法交流可以家魏鑫:lixiaowu1129,一起探讨iOS相关技术!
    本人亲测有效!绝对可靠!更多方法交流可以家魏鑫:lixiaowu1129,一起探讨iOS相关技术!
    本人亲测有效!绝对可靠!更多方法交流可以家魏鑫:lixiaowu1129,一起探讨iOS相关技术!

    一、swift怎么用oc定义的宏?

    1、在swift中,能直接使用定义为常量的宏,不能使用带有方法调用的宏,也不能使用静态常量。

    下面这种定义为常量的宏可以使用
    #define APP_LANGUAGE_EN @"en" 
    #define kNavigationBarHeight 44.0
    
    下面带有方法调用的宏不可以使用
    #define kScreenHeight [[UIScreen mainScreen] bounds].size.height
    #define kScreenWidth [[UIScreen mainScreen] bounds].size.width
    
    下面带有静态常量swift不能使用,可以改成宏
    static NSString *const StopTabRefreshNotifyNameHtml = @"TabRefreshNotifyNameHtml";
    复制代码
    

    2、如何解决? 在公共*.swift文件里面重新定义带有方法调用的宏。

    image.png

    二、如何加载字符串、图片资源?

    之前我们开发oc组件时候一般会使用宏定义来加载资源,由于在swift不能使用带有方法调用的宏,所以可以专门写一个类,使用静态方法来加载资源

    image.png

    三、swift组件如何暴露接口给业务方调用?

    由于我们组件化架构是使用BeeHive来暴露接口的,所以swift组件还是得遵循这个规范,仍然可以service和delegate的方式来跟业务方交互

    1、暴露接口给业务方使用

    image.png

    2、获取delegte

    image.png

    3、怎么判断一个协议是否实现了某个方法?

    1)用respondsToSelector判断,判断的方法可以定义为@required或者@optional

    if let delegate = ((BHConfig.get(BPChowder.delegateName)) as? BPChowderDelegate) {
                if delegate.responds(to: #selector(BPChowderDelegate.getURLH5(_:))){
                    let url = delegate.getURLH5("/faq/privacy")
                    BPCommonJumpModel .jump(withRouterUrl: url, fromVC: self, shouldPresent: false)
                }
            }
    复制代码
    

    2)用可选链调用。判断的方法必须定义为@optional,否则编译报错

    let delegate = ((BHConfig.get(BPChowder.delegateName)) as? BPChowderDelegate)
    
            if let url = delegate?.getURLH5?("/faq/privacy"){
    
                BPCommonJumpModel .jump(withRouterUrl: url, fromVC: self, shouldPresent: false)
            }
    复制代码
    

    4、在Swift组件中会需要创建BeeHive的Service,如BPChowderService,它不能改成swift版,只能使用OC版

    原因:BeeHive使用NSClassFromString创建BPChowderService类,若BPChowderService是swift类会创建失败
    
    - (Class)serviceImplClass:(Protocol *)service
    {
        NSString *serviceImpl = [[self servicesDict] objectForKey:NSStringFromProtocol(service)];
        if (serviceImpl.length > 0) {
            return NSClassFromString(serviceImpl);
        }
        return nil;
    }
    复制代码
    

    四、如何使用懒加载属性

    在oc中写业务,经常使用懒加载,swift中懒加载属性写法如下

    Swift中懒加载只会执行一次,将属性置为nil,不会再触发懒加载

    image.png

    五、注意值类型和引用类型的区别

    在oc中,数组,字典这些都是引用类型,在swift中变成了值类型,理解这点很重要,要不然很容易写出不符合预期的代码

    比如下面这段代码,执行完sectionArr1.append(model) 后tempSectionDataArr依然是空数组,因为sectionArr1加入到tempSectionDataArr,再改变sectionArr1不会影响到tempSectionDataArr,这是因为数组是值类型。

    正确的方法是tempSectionDataArr[0].append(model)

    var tempSectionDataArr: [[BPAboutCellModel]] = []
    
    var sectionArr1: [BPAboutCellModel] = []
    tempSectionDataArr.append(sectionArr1)
    
    var model = BPAboutCellModel()
    model.leftIconName = "about_callcenter"
    model.mainMessage = BPChowder.localizable("AboutCallCenter")
    model.subMessage = "02-033-0080"
    model.clickBlock = { [weak self] in
    
    let num = "tel://(String(describing: CALLCENTER))" //number为号码字符串 如果使用这个方法 结束电话之后会进入联系人列表
    let url = URL(string: num)
    if let url = url {
    UIApplication.shared.openURL(url)
    }
    
    BlueAFTracker.recordClickEvent(withPageName: self?.pageName, viewName: "view_call_center", params: nil, shouldReportToGA: false)
    }
    //下面两行的写法结果不一样
    sectionArr1.append(model) //tempSectionDataArr依然为空
    tempSectionDataArr[0].append(model) //tempSectionDataArr是个维数组
    复制代码
    

    六、继承BasicViewController如何不写init方法进行初始化?

    BasicViewController的init方法里面调用了onInit方法,子类可以通过重写该方法进行初始化

    image.png

    特别注意:
    子类只要有 convernce init方法
    一定需要添加一个 resign init方法,否则编译不通过

    七、if 可选绑定的坑

    if let isShow = false {
        block1()
    } else {
        block2()
    }
    
    若isShow为false 也会执行block1(),它只判断是否有值
    复制代码
    
    image.png

    八、版本判断

    !!!错误方式!!!
    //直接这种方式会失败 version=0
    let version = Double(UIDevice.current.systemVersion)  
    
    !!!Swift中使用以下方法判断版本!!!
    方法一:
    let version = (UIDevice.current.systemVersion as? NSString).doubleValue 
    方法二:
    if #available(iOS 13, *) {
        // >= 13.0
    } else {
        // 
    }
    复制代码
    

    九、编译问题

    1、上次能编译过,没有改动代码,这次编译不过,怎么办?

    clean一下再重新编译,如果还是不行,执行pod install,再不行就重启xcode,再不行重启电脑。。

    十、遇到Redefinition of module 'xxx' 编译报错怎么办?\

    引入swift混编后,可能会遇到Redefinition of module 'xxx' 报错,比如Redefinition of module 'FBSDKCoreKit' ,原因是主工程有两个FBSDKCoreKit.modulemap。这个时候可以执行如下操作:

    1、先删除主工程中的两个FBSDKCoreKit.modulemap。

    2、重新pod install 。

    3、重新编译。

    十一、打包时候需要内嵌静态库,要不然在 iOS 12.2以下系统会崩溃。

    把编译选项改成 always embed swift standard libraries 改为YES

    相关文章

      网友评论

          本文标题:iOS Swift开发遇到的问题汇总

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