美文网首页
iOS 几个问题记录

iOS 几个问题记录

作者: 大冯宇宙 | 来源:发表于2018-12-21 17:36 被阅读0次

1. Weex单利卡顿

最近修复了一个播放器卡顿的问题,现象是播放器播放一段时间后会产生卡顿,原因是我们发现weex像原生发送js指令的时候,会将所有指令存下来,判断就是单利的锅。因为播放器的进度条会不断的更改,所以存放指令的数组就会越来越大,下边的图片是播放了几分钟后的数组达到了上万个数据,而且在一直的循环,解决方案,我们把进度条的操作放到了原生来控制。

2.友盟的启动崩溃

最近解决了个启动崩溃的问题,看到log里是友盟的数据库崩掉了。因为我们使用了weex,判断是多线程共享了友盟的数据库连接,导致崩掉了。最后的解决方案,是将友盟的所有操作,放到了一个操作队列中,解决了崩溃问题。

SQLite的三种线程问题:

    单线程:禁用所有的mutex锁,并发使用时会出错。当SQLite编译时加了SQLITE_THREADSAFE=0参数,或者在初始化SQLite前调用sqlite3_config(SQLITE_CONFIG_SINGLETHREAD)时启用。

    多线程:只要一个数据库连接不被多个线程同时使用就是安全的。源码中是启用bCoreMutex,禁用bFullMutex。实际上就是禁用数据库连接和prepared statement(准备好的语句)上的锁,因此不能在多个线程中并发使用同一个数据库连接或prepared statement。当SQLite编译时加了SQLITE_THREADSAFE=2参数时默认启用。若SQLITE_THREADSAFE不为0,可以在初始化SQLite前,调用sqlite3_config(SQLITE_CONFIG_MULTITHREAD)启用;或者在创建数据库连接时,设置SQLITE_OPEN_NOMUTEX flag。

    串行:启用所有的锁,包括bCoreMutex和bFullMutex。因为数据库连接和prepared statement都已加锁,所以多线程使用这些对象时没法并发,也就变成串行了。当SQLite编译时加了SQLITE_THREADSAFE=1参数时默认启用。若SQLITE_THREADSAFE不为0,可以在初始化SQLite前,调用sqlite3_config(SQLITE_CONFIG_SERIALIZED)启用;或者在创建数据库连接时,设置SQLITE_OPEN_FULLMUTEX flag。

保证线程安全的话,4种方式:

    SQLite使用单线程模式,用一个专门的线程访问数据库。

    SQLite使用单线程模式,用一个线程队列来访问数据库,队列一次只允许一个线程执行,队列里的线程共用一个数据库连接。(适用范围更广,效率也足够优秀,一般应采用这种方式,在测试的时候,完全是数据库的操作,正常我们再操作数据库的时候,也会进行其他文件的IO,所以建议其他的IO放在别的线程中)

    SQLite使用多线程模式,每个线程创建自己的数据库连接。(效率最低的,不建议使用)

    SQLite使用串行模式,所有线程共用全局的数据库连接。(读取性能更高,适合无需使用事务的场合)

结论:可以将第二和第四种的数据库访问方式结合起来使用,利用两个串行队列,分别持有读和写操作,每个队列持有一个数据库连接。当然如果没遇到数据库瓶颈的话,第二种单线程模式就足够使用了。

这篇帖子对数据库的多线程写的很详细。

3.scrollview 嵌套 tableview 的上下联动效果(效果-极客时间-极客新闻列表页面)

核心代码:

思路:通过两个变量来判断scrollview 和 tableview是否可以滑动,如果scrollview 滑动到指定位置,则设置scrollview的偏移量未固定值,然后会响应tableview,反之亦然。

scrollview 要响应手势穿透,则需要继承scrollview 重写方法

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer

{

    return YES;

}

以下方法在controller中实现

- (void)setVcCanScroll:(BOOL)vcCanScroll

{

    _vcCanScroll= vcCanScroll;

    if (!vcCanScroll) {//如果cell不能滑动,代表到了顶部,修改所有子vc的状态回到顶部

        self.tableView.contentOffset = CGPointZero;

    }

}

// 这两个代理方法是解决在滑动到最下边的时候,tableview不能滑动的问题

- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate{

    //decelerate:减速动画,当为YES时,有滑动减速动画,NO时,没有滑动减速动画

    if(!decelerate){

        //没有减速动画的时候,UIScrollView真正停止在这

        if(self.tableView== scrollView) {

            if(scrollView.contentOffset.y+ scrollView.height>= scrollView.contentSize.height) {

                scrollView.contentOffset=CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y-1);

            }

        }

    }}

- (void)scrollViewDidEndDecelerating:(UIScrollView*)scrollView{

    //有减速动画的时候,UIScrollView真正停止在这

    if(self.tableView== scrollView) {

        if(scrollView.contentOffset.y+ scrollView.height>=floor(scrollView.contentSize.height)) {

            scrollView.contentOffset=CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y-1);

        }

    }

}

// 主控制协议

- (void)scrollViewDidScroll:(UIScrollView*)scrollView {

    if(self.scrollView== scrollView) {

        CGFloatbottomCellOffset =ScrollOffset;

        if(scrollView.contentOffset.y>= bottomCellOffset) {

            scrollView.contentOffset=CGPointMake(0, bottomCellOffset);

            if(self.canScroll) {

                self.canScroll=NO;

                self.vcCanScroll=YES;

            }

        }else{

            if(!self.canScroll) {//子视图没到顶部

                scrollView.contentOffset=CGPointMake(0, bottomCellOffset);

            }

        }

        if(scrollView.contentOffset.y> -GKT_STATUS_BAR_HEIGHT) {

            self.imageViewShow.alpha = (GKT_STATUS_BAR_HEIGHT+scrollView.contentOffset.y) / (GKT_STATUS_BAR_HEIGHT + ScrollOffset);

        }else{

            self.imageViewShow.alpha=0;

        }

        scrollView.showsVerticalScrollIndicator = _canScroll?YES:NO;

    }

    if(self.tableView== scrollView) {

        if(!self.vcCanScroll) {

            scrollView.contentOffset=CGPointZero;

        }

        if(scrollView.contentOffset.y<=0) {

            scrollView.contentOffset=CGPointZero;

            self.canScroll=YES;

            self.vcCanScroll=NO;

        }

        scrollView.showsVerticalScrollIndicator = _vcCanScroll?YES:NO;

    }

}

4.iOS的色彩空间:

在蓝狐上的UI颜色,跟Storyboard上设置的颜色不一样,通常蓝狐的颜色更浅一些,但是用代码设置的颜色跟蓝狐是一样的。为什么出现了这个问题?原因是色彩空间不一样,这个有个帖子说的挺详细,简单的说xib上默认的色彩空间是

xib默认色彩空间

而设计师出图的色彩空间是sRGB,所以颜色就对不上了。

解决方案就是把色彩空间换成跟设计师的一样就OK了。通过这个我们可以回想一下为啥用系统自带的取色器取出来的颜色跟想要的颜色对不上,原因就是这个。

5.iOS的tableviewcell的高度计算误差:

在开发时候使用了xib来构造cell,发现其中的label计算的高度不正确,如果label使用的xib设置字体,那改成代码设置的字体试试。

6.一个上架问题:

*  2. 1 Performance: App Completeness

*  Guideline 2.1 - Information Needed

*  This type of app has been identified as one that may violate one or more of the following App Store Review Guidelines. Specifically,these types of apps often:

*  1.1.6 - Include false information,features,or misleading metadata

*  2.3.0 - Undergo significant concept changes after approval

*  2.3.1 - Have hidden or undocumented features,including hidden "switches" that redirect to a gambling or lottery website

*  3.1.1 - Use payment mechanisms other than in-app purchase to unlock features or functionality in the app

*  3.2.1 - Do not come from the financial institution performing the loan services

*  4.3.0 - Are a duplicate of another app or are conspicuously similar to another app

*  5.2.1 - Were not submitted by the legal entity that owns and is responsible for offering any services provided by the app

*  5.2.3 - Facilitate illegal file sharing or include the ability to save,convert,or download media from third party sources without explicit authorization from those sources

*  5.3.4 - Do not have the necessary licensing and permissions for all the locations where the app is used

应该不少同学会收到苹果发来的拒绝邮件,通常咱们的做法就是各种查,最后发现没毛病。笔者也跟苹果扯了几次皮,最后解决方案就是给苹果回复邮件,写个保证,说本程序没有违反上述问题,这个过程中也不要提审,只单独回复邮件,然后苹果会给你回复,来回聊几句,那边直接就给你过审了。

相关文章

网友评论

      本文标题:iOS 几个问题记录

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