为什么dispatch_sync在主线程会死锁

首先看下面一段代码 dispatch_queue_t queue = dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL); dispatch_sync(queue, ^{//taskA //do something dispatch_sync(queue, ^{//taskB //啥也干不了 }); });     dispatch_sync函数用于将一个block(任务)提交到队列中同步执行,直到block执行完后,这个函数才会返回。queue是一个串行队列,如果先后加入两个任务,taskA和taskB, 那么只有taskA执行完之后taskB才能执行。如果taskB是在taskA中加进队列的,那么它们依然遵守先进先出原则,即taskA执行完之后taskB才执行,也就是taskB在等待taskA完成。但是因为dispatch_sync的同步特性,taskB执行不完taskA就不算完成,即taskA在等待taskB的完成,这样就发生了死锁。 根据上面那份代码,我们就可以理解下面的代码为什么会阻塞主线程了。 dis....

阅读全文 »

关于连续触发的函数中动画异常的描述

我想要的过程是这样的,我有两个label像球场上的广告牌一样交替滚动,当前的往上移动逐渐消失下边的从下边同时往上移动逐渐出现。我为了在autolayout下也能实现所以一开始准备用transform实现,但是发现往上移动的动画异常,不知道什么原因,让人郁闷。。。便秘的感觉很久之后,我决定退而求其次,用改变center来实现,问题解决了,但是是建立在我这两个label没有autolayout的基础之上。今天特此记下,留待以后研究。

阅读全文 »

仿QQ左侧滑动菜单的实现

冲动 最近接手的一个老项目有个侧滑菜单的需求,这个老项目的侧滑菜单用了网络上的一个第三方库,但是这个库竟然没有处理好导航条的显示,以至于项目中很多需要导航条展示信息的视图都通过添加subView的方式模仿了导航条。这简直是暴殄天物啊,放着真正的导航栏那强大的作用不用,浪费了多少时间和精力啊,都是青春啊,开发的前路上早已挖了无数的坑等着身心疲惫的我们往里跳啊。对此深恶痛绝的我,早就下了不杀此贼誓不罢休的决心。好吧,最近看三国看的有点多了。 暗渡陈仓 我在无所不能的GitHub上搜索侧滑菜单项目,试验了各种,发觉没有能很好的符合当前项目需求。我们当前的项目需求是跟手机QQ左侧滑动菜单一样的效果,有个默认的主视图,然后其他视图的展示都是在这个视图的基础上push出来的。当然把这些项目改造出这种功能其实也不难,但是左侧菜单的视差效果都跟QQ相差甚远,唯一相似的就是RESideMenu这个比较有名的项目,但是它的视差效果是菜单在展示过程中由比较大然后缩放到实际大小,感觉不如QQ的效果好,怎奈我当时心情比骄傲浮躁,改了个参数也没调出想要的效果来,于是一怒之下决定自己写一个。事后,发现有个Swi....

阅读全文 »

回头看UITableView(三)-下拉刷新的实现

最近陷入了项目中一个日历月视图与周视图切换效果的实现,长时间没有实现想要的效果,沮丧至极。烦请有好想法的同学指点一二,在线等@留什么白。 结束例行的啰嗦,进入正题。 大家可能都用过MJRefresh,十分之方便,李明杰老师借助runtime的特性,极尽之能,让千千万万小白开发者和遵循不重复制造轮子原则的开发者用最少的代码就实现了界面下拉刷新的功能。我们今天不谈runtime的黑魔法,而是UITableView最常见的刷新数据方式下拉刷新的实现过程。 首先,我们定义三个枚举值 typedef NS_ENUM(NSUInteger, RefreshState) {     RefreshStateNormal,//正常     RefreshStatePulling,//释放即可刷新     RefreshStateLoading,//加载中 }; 分别表示正常状态、释放即可刷新状态、加载中状态 为了简单说明,我们只用一个UILabel来表现就可以,把它放在内容上方,也就是正常情况下看不到的地方,只有下拉的时候才能看到。 然....

阅读全文 »

回头看UITableView(二)-父视图UIScrollView

题目早早就定下了,现在想填充内容了,踌躇中却不知道从哪里开始了。 窗外突然下起雨来。虽然不愿承认,但夏天确实已经渐去渐远,凉意开始蔓延。索性放空身心,伴着雨声入眠吧。 I'm back! 众所周知,UITableView的父视图就是UIScrollView,UITableView之所以能滚动就是基于UIScrollView的特性,今天咱们就来深入理解一下UIScrollView。 上图: 打码: - (IBAction)boundsAction:(UIStepper *)sender { self.redView.bounds = CGRectMake(0, sender.value, self.redView.bounds.size.width, self.redView.bounds.size.height);     self.boundsLabel.text = [NSString stringWithFormat:@"红色视图bounds%@",NSStringFromCGRect(self.redView.bounds)]; } 我如果说改变bou....

阅读全文 »

回头看之UITableView-(基本代理方法及复用原理)

UITableVIew是iOS开发中最常见的视图中最经典的视图了,没有之一,相信对这个视图敢称精通的人开发个好应用应该是问题不大的。 闲话少叙,进入正题。 怎么使用 掌握两个代理 UITableViewDelegate @optional //下文再提到该方法用heightForRow代替 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; UITableViewDataSource @required //下文再提到该方法用numberOfRowsInSection代替 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; //下文再提到该方法用cellForRow代替 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtInd....

阅读全文 »

ReactiveCocoa解读-订阅信号

信号(Signal)和订阅者(Subscriber)是在ReactiveCocoa( 下文简称RAC)的相关资料中提到最多的概念了,但因为是从英文语境中直接翻译过来的,让国内大部分开发者对订阅信号一时难以理解,即使掌握了RAC的用法对此还是模棱两可。今天,我们尝试从RAC的源码去解读,看看订阅信号到底是个啥子过程。 先上一段RAC最简单的使用方法。 RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {         [subscriber sendNext:@"钢铁锅"];         [subscriber sendNext:@"含眼泪喊修瓢锅"];         [subscriber sendNext:@"坏缺烂角的换新锅瓢乱放"];         [subscrib....

阅读全文 »