iCarousel 我的世界1.8.1服务器 如何循环

1603人阅读
iOS相关(49)
1、请问ios的软件如何编程,与MsSQL服务器连接,读取信息。我正在开发的一个APP,需要调用一个MsSQL服务器的数据,不知谁可以给我介绍一下,或者告诉我一下,在哪个网站或哪本书可以找到相关信息,谢谢
==========================
不能通过设备直接连接远程sql只能连接本地sql 那请问一下,一般性的,如网易新闻的APP,它是如何从远程服务器端下载数据的呢?还有,如何把数据上传到服务器端呢?有没有相关的文献? 服务端设置下数据源, 我的做法是在服务端提供api接口, 返回的是json数据,, 然后iphone上读取json
2、求网易内容图文混排的做法
不是用的webview,应该是CoreText
==========================
扯,网易新闻使用的是UIWebView,自己长按下看看它弹出的菜单就知道了!.如果使用CoreText样式就必须事先确定好,完全失去了页面的灵活性.另外,CoreText自己用过了没有?没有使用过就别误导别人行么?要知道CoreText对中文字体支持很差的(ios6.0以下系统),所有CoreText在ios6以下的系统中文都是粗体的 学习了。。。话说我在app4下载得几款开源字体框架,涉及到中文,日文效果都不好。。。原来如此。。。。 解析HTML之后再用coreText画也能很灵活不过网易的图片加载方式到真的很像UIWebView
解析HTML,单说最常用的: 文字,图片,超链接,字体颜色,按钮,表情。 自己画,复杂度不低呀.
3、请教关于非paging的ScrollView首尾相接循环实现的方法
我想实现一个类似网易新闻的菜单栏,要能够左右滑动,点选其中任何一项时,被点选的那一项会动画滑动至屏幕中间。正因为这样的需求,当点选最靠近scrollview边缘的那些项时,如果此时该项滑至中间,则会导致边缘出现空白,这属于视觉上瑕疵。故而希望能够实现首尾相接无限循环的功能。但是看了网上和坛子里面的sample,几乎都是基于scrollview的paging属性是YES时来实现的,但是我的是非paging的。可参考的App:音悦台 就是上面的那个“首播”、“日本”、“内地”那个效果
==========================&
其实这个简单的解决逻辑就是不允许滑动,你去截手指滑动的事件,然后scroll用2或者3倍的备用长度去填,就可以实现你要的效果了,先做做看吧,要是有困难再去找音悦台那俩家伙打听打听 问题已解决!结贴!解决方案:第三方开源库 iCarousel 可以根据自己的具体需求,去做修改。 我靠,你咋知道音悦台就两家伙在开发啊。。我们就是用的 iCarousel 修改的。
4、UIwebview 点击图片 放大效果实现
就是类似网易新闻那个应用的样式,新闻展示那个界面,点击新闻图片,从图片所在位置开始放大的效果有疑问的地方是如何知道是点击的图片的位置,难道是坐标转换来实现的?,这个很有趣。。有知道的朋友请指教下
==========================
&加tap手势就好了啊,加什么button发回来的sender坐标就是被点击的东西的坐标
5、请问这种点一下出来黑色上面有几个按钮的是什么组件做的?
如网易新闻客户端:&
==========================&
自己写个uiview不就好了么。。。 UIMenuController、UIMenuItem腾讯的是自己做的view。UIMenuItem并非继承自UIView,所以替换图片是不可能的。就知道这么多
6、iphone网易新闻带箭头弹出菜单用的什么控件
请问iphone网易新闻中点击info按钮出现的带箭头的弹出菜单是怎么实现的(不是edit menu),自制的view?还是某模式view,菜单中貌似是tableview样式的?在ipad中的popover可以实现,但是在iphone中呢 描述:网易新闻截图图片:小截图.png ==========================
&iphone中没有popover,应该是他们自己做的。实现起来不难,加个subview。 用button uiview 拼起来 能做到这样的 上面就不是导航栏而是个view导航栏挨不上 找个带箭头的图片 背景view 透明 上面加button 就可以了imageView=[[UIImageView alloc] initWithImage:[[UIImageimageNamed:@&PopoverTopArrowLeft.png&]stretchableImageWithLeftCapWidth:47.0
topCapHeight:35.0] ]; 原来是导航栏的问题,谢谢大侠指点,
7、网易新闻3.0版本的支持drag的push导航是如何实现的?
网易新闻3.0版本的采用了抽屉式的导航,支持拖拽手势的渐进,请教一下实现思路,就是点击新闻列表进入到新闻详情,在新闻详情的页面可以通过手势拖拽回去,背景会有个变暗变亮的特效,请问这个导航的实现思路是什么?用pushViewController和presentModalViewController都不行,难道是直接addsubview??
==========================&
我知道思路了,网易的导航在普通视图的基础上做了美化。1.网易3.X的top视图左右两边是加了阴影的。2.top视图移出后,背景视图会加个遮罩层,说白了就是在下面的视图上加个透明黑的视图,top视图移出的过程中对遮罩层做个透明度的渐变,下面的视图同时做缩放处理。 分屏效果的demo在Path2DemoPrj.zip中
8、求教网易新闻的展示方式
网易新闻的客户端,新闻详情页面的图文混排等各种效果是用啥做的捏
==========================&
UIWebView能实现 不像网页啊......能调字体的 UIWebView展现的网页,是不能改变字体的吧? 可以改变字体,配合JS使用。。。
9、请问网易新闻的头条导航如果实现
请问网易新闻的头条,科技导航如果实现&
==========================&
可以通过很多种方式实现例如每个标题做成一个UIButton,加上标题,背景做成透明,透明的button底下放红色的背景,点击button的时候移动后面的背景。还有很多其他的方式,欢迎补充 leftItem,rightItem&-UIBarButtonItem&-initWithCustomView&-view 如何实现点击button的时候移动后面的背景。
10、哪位高手来分析下网易新闻客户端和新浪微博客户端的控件布局和大致的实现流程
如题:哪位高手来分析下网易新闻客户端和新浪微博客户端的控件布局和大致的实现流程做了多年开发,主要是在微软体系,MFC,c++,刚开始研究ios,下面是我的简单分析,希望有高手做更深入的分析,不足之处请指正,谢谢啦---------------------------------------------------------------------------------------------------------注:本人做了多年开发,脱离ios平台,做通讯,网络,多线程,内核都不是问题,偏后端,前端技术只对微软平台研究的比较透,移动互联网的热潮不希望错过,希望大家回贴啊,一起学习,不熟悉的朋友也可以讲讲自己的开发经历啊如图:新浪微博:最上面是一个ToolBar下面是一个ScrollView,然后在ScrollView中会有自己发送的内容,以及转发
内容,转发内容中会有图片等 信息网易:最上面的是一个ToolBar?最下面分了几个viewController,分别是新闻,话题,2012.。。新闻这个view中,最上面开始,有头条,体育,娱乐,等,这个是用哪个控件的?下面的滚动广告,是Page Control,再下面的新闻列表是Table view
==========================&
网易新闻上面横向滚动可以用一个自定义横向ScrollView来实现...我感觉新浪微博的列表用的是TableView....如果用ScrollView自己写回收,写加载很麻烦,估计列表都会用苹果封装好的TableViewsina :status bar ,navigationbar(leftbarbuttonitem 有2个,自定义了 titileview) ,tableview tabbar当前页面结构上应该是 UITabbarController +NavigationController网易: status
bar ,navigationbar ,自定义UIScrollView*2,tableview, 自定义 tabbar当前页面结构上应该是 UITabbarController +NavigationController 对,当时写错了,应该用的是tableview 刚才试着自己用xcode布局了一下网易的部分界面,大家看看对不对?图片:111.png 图画的丑了一点,是这个意思,呵呵 我最感兴趣的地方在于网易客户端那个左右翻页时候path效果以及同时出现的灰色阴影、新闻阅读页出现时的效果等
11、有谁知道网易新闻ios客户端的页面滑动效果怎么做?
最近公司一定要我做一个类似网易新闻客户端的效果出来,如果做好了将要把之前的项目翻新重新构造成那种界面效果。目前我已根据网上的相关资料做出了左右滑动的效果,使用的手势,但是公司的人说滑动没别人的流畅,继续改进。又要求做点击表格cell,push到新页面后再滑动返回,同样要那种有阴影加能缩小的动画,但是我们项目的内容必须是表格,我尝试了自定义tableview,重写里面的touch事件来滑动,但是效果非常不理想。很卡,也会同时触发tableview的点击事件,所以否定了这个办法。如果有知道的大侠跟我说一声,到底是怎么做的呀,我需要的是能在tableview上左右滑动返回,点击cell就push到新界面。帮帮忙啊,这个问题困扰我很久了,也尝试了N中办法。如果不清楚我说的,可以看一下网易新闻app效果。谢谢啦!唉……
==========================&
今天又苦思冥想了一天,终于有点收获啦,使用二楼的那种页面push,不过不用touch事件,而使用手势,这样就不会有同时触发的问题了。继续努力啊,心情终于好点了,谢谢大家的热心! – jily-1816:17 回复嗯,这个我也看过了,昨天已经试了。因为navgationController上面加的tableview,所以手势会被拦截,后面我自定义table,将手势传递下去,但是会同时触发滑动和点击事件,而且滑动的会特别不流畅。基本上不行啊!所以要继续考虑从手势方面考虑,而不能使用touch事件。不过touch的做法很有借鉴意义!谢谢你啦!
– jily-1809:39呵呵,要是能这么扬眉吐气的说这话,那我不愧对自己了!天天被压迫着,看人脸色,为了生活还是得多忍受啊!加工资这事,在这个公司几乎不太可能,一年才给加一次,而且少的可怜!马云那句话还说的真没错!哎…… 就是一个TableView在ScrollView中啊table的宽度是320.scroll的高度是显示高度 所以上下滑动时tableview 响应左右滑动时scrollView响应当table滑动时scroll不能动。然后根据自己的需要做效果就ok了啊想问下楼主实现了吗我和楼主一样
tableview始终掩盖了touchbegan的方法,重写tableview,然后在tableview的touch事件中重新调navigationController的touch事件,但是动画非常不流畅,不知道楼主最后怎么解决的解决了,给你点提示:不是重写tableview的touch事件,而是使用手势,把发生在touch事件里的动作全部转化在手势的委托事件里面做。楼上设为答案的那个demo你看看,希望有所启发!
12、像IPHONE主屏幕一样,可以手指滑动翻页的效果要怎么做?
==========================
&把coming,going 换成相应的就可以了
1. [UIViewbeginAnimations:@&View Flip& context:nil];
2. [UIViewsetAnimationDuration:1.25];
3. [UIViewsetAnimationCurve:UIViewAnimationCurveEaseInOut];
5. UIViewController *coming =[[UIViewController alloc] init];
6. UIViewController *going= [[UIViewController alloc] init];
7. UIViewAnimationT
9. coming.view =self.view.
10. going.view = self.
11. transition =UIViewAnimationTransitionCurlUp;
14. //[UIViewsetAnimationTransition:transition forView:self.view cache:YES];
15. [UIViewsetAnimationTransition:transition forView:self.view.superview cache:YES];
17. [coming viewWillAppear:YES];
18. [going viewWillDisappear:YES];
19. [going.view removeFromSuperview];
20. [going viewDidDisappear:YES];
21. [coming viewDidAppear:YES];
23. [UIView commitAnimations];&
用CA模拟一定要费事一些,UIScrollView有特色:1 手指向左滑,左边的一屏出来一点点的时候,松开手指,人家能弹回去。2 滑到最后一页继续往左滑,松开手指,人家有橡皮筋的效果。3 人家可以配合UIPageControl。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:821375次
积分:9693
积分:9693
排名:第1174名
原创:188篇
转载:133篇
评论:370条
(3)(3)(1)(7)(13)(1)(1)(1)(1)(5)(3)(8)(2)(3)(3)(4)(3)(3)(14)(1)(5)(12)(38)(97)(15)(5)(5)(9)(10)(7)(1)(12)(9)(1)(8)(8)(1)Pages: 1/2
主题 : ❖❖最好用的无限循环轮播图❖❖ --- DYMRollingBanner
级别: 圣骑士
可可豆: 1970 CB
威望: 1953 点
在线时间: 382(时)
发自: Web Page
来源于&&分类
❖❖最好用的无限循环轮播图❖❖ --- DYMRollingBanner&&&
我最近也写了一个无限轮播图,开源到了cocoapods,在此顺便也分享给大家:pod 'DYMRollingBanner', '~& 2.1.2'Github地址:特点:1. 无限轮播2. 支持本地和远程图片3. 支持自动播放,时间可调4. 拖拽时暂停自动播放,刚开后继续5. 轮播图内存池机制,有效节约内存,大小可调6. 基于Block的点击事件处理7. 100%支持Autolayout8. 代码清晰,易于使用[ 此帖被dymx101在 09:09重新编辑 ]
图片:demo.gif
图片:create_thumb.png
&a href='/app/id'&&img src='https://static-s.aa-cdn.net/img/ios/cc4deaca7c9b72cfa2005'&&/a&
级别: 圣骑士
可可豆: 1970 CB
威望: 1953 点
在线时间: 382(时)
发自: Web Page
自己顶一个
&a href='/app/id'&&img src='https://static-s.aa-cdn.net/img/ios/cc4deaca7c9b72cfa2005'&&/a&
级别: 圣骑士
可可豆: 1970 CB
威望: 1953 点
在线时间: 382(时)
发自: Web Page
&a href='/app/id'&&img src='https://static-s.aa-cdn.net/img/ios/cc4deaca7c9b72cfa2005'&&/a&
级别: 新手上路
UID: 510863
可可豆: 93 CB
威望: 71 点
在线时间: 21(时)
发自: Web Page
我是一个初学者为什么我导不进去给我提示[!] Unable to satisfy the following requirements:
下午7.42.53.png
级别: 圣骑士
可可豆: 1970 CB
威望: 1953 点
在线时间: 382(时)
发自: Web Page
回 3楼(wgt393866) 的帖子
看看你podfile里面有没有这一句:platform :ios, '7.0'需要指定platform为7.0以上今天刚push了更新的2.1.4版本到git:pod 'DYMRollingBanner', '2.1.4'Pod Spec提交记录:[ 此帖被dymx101在 22:26重新编辑 ]
&a href='/app/id'&&img src='https://static-s.aa-cdn.net/img/ios/cc4deaca7c9b72cfa2005'&&/a&
级别: 侠客
UID: 480775
可可豆: 286 CB
威望: 276 点
在线时间: 347(时)
发自: Web Page
可以带缝隙吗?最近做这个带缝隙的 都纠结死了!
图片:588C1CCB-381C-4A4B-A9DD-B5.jpg
级别: 圣骑士
可可豆: 1970 CB
威望: 1953 点
在线时间: 382(时)
发自: Web Page
回 5楼(gavin_gxz) 的帖子
这种用iCarousel可能比较适合:
&a href='/app/id'&&img src='https://static-s.aa-cdn.net/img/ios/cc4deaca7c9b72cfa2005'&&/a&
级别: 骑士
UID: 300379
可可豆: 880 CB
威望: 776 点
在线时间: 254(时)
发自: Web Page
都好屌啊啊啊啊啊啊啊
级别: 圣骑士
可可豆: 1067 CB
威望: 1067 点
在线时间: 1041(时)
发自: Web Page
why you so diao?
级别: 圣骑士
可可豆: 1067 CB
威望: 1067 点
在线时间: 1041(时)
发自: Web Page
回 6楼(dymx101) 的帖子
借贵地问一下 类似qq 好友动态 栏目,有多种样式的tableViewcell怎么实现,有一张图片的,还有多张图片的,甚至还有视频
Pages: 1/2
关注本帖(如果有新回复会站内信通知您)
4*5+2 正确答案:22
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版实例化讲解 RunLoop
实例化讲解&RunLoop&
实例化讲解RunLoop
之前看过很多有关RunLoop的文章,其中要么是主要介绍RunLoop的基本概念,要么是主要讲解RunLoop的底层原理,很少用真正的实例来讲解RunLoop的,这其中有大部分原因是由于大家在项目中很少能用到RunLoop吧。基于这种原因,本文中将用很少的篇幅来对基础内容做以介绍,然后主要利用实例来加深大家对RunLoop的理解,本文中的代码已经上传GitHub,大家可以下载查看,有问题欢迎Issue我。本文主要分为如下几个部分:
RunLoop的基础知识
初识RunLoop,如何让RunLoop进驻线程
深入理解Perform Selector
一直”活着”的后台线程
深入理解NSTimer
让两个后台线程有依赖性的一种方式
NSURLConnetction的内部实现
AFNetWorking中是如何使用RunLoop的?
其它:利用GCD实现定时器功能
一、RunLoop的基本概念:
什么是RunLoop?提到RunLoop,我们一般都会提到线程,这是为什么呢?先来看下官方对RunLoop的定义:RunLoop系统中和线程相关的基础架构的组成部分(和线程相关),一个RunLoop是一个事件处理环,系统利用这个事件处理环来安排事务,协调输入的各种事件。RunLoop的目的是让你的线程在有工作的时候忙碌,没有工作的时候休眠(和线程相关)。可能这样说你还不是特别清楚RunLoop究竟是用来做什么的,打个比方来说明:我们把线程比作一辆跑车,把这辆跑车的主人比作RunLoop,那么在没有’主人’的时候,这个跑车的生命是直线型的,其启动,运行完之后就会废弃(没有人对其进行控制,’撞坏’被收回),当有了RunLoop这个主人之后,‘线程’这辆跑车的生命就有了保障,这个时候,跑车的生命是环形的,并且在主人有比赛任务的时候就会被RunLoop这个主人所唤醒,在没有任务的时候可以休眠(在IOS中,开启线程是很消耗性能的,开启主线程要消耗1M内存,开启一个后台线程需要消耗512k内存,我们应当在线程没有任务的时候休眠,来释放所占用的资源,以便CPU进行更加高效的工作),这样可以增加跑车的效率,也就是说RunLoop是为线程所服务的。这个例子有点不是很贴切,线程和RunLoop之间是以键值对的形式一一对应的,其中key是thread,value是runLoop(这点可以从苹果公开的源码中看出来),其实RunLoop是管理线程的一种机制,这种机制不仅在IOS上有,在Node.js中的EventLoop,Android中的Looper,都有类似的模式。刚才所说的比赛任务就是唤醒跑车这个线程的一个RunLoop
Mode就是,一系列输入的source,timer以及observer,RunLoop Mode包含以下几种: NSDefaultRunLoopMode,NSEventTrackingRunLoopMode,UIInitializationRunLoopMode,NSRunLoopCommonModes,NSConnectionReplyMode,NSModalPanelRunLoopMode,至于这些mode各自的含义,读者可自己查询,网上不乏这类资源;
二、初识RunLoop,如何让RunLoop进驻线程
我们在主线程中添加如下代码:
&&&&NSLog(@&while
the thread be blocked here
&&&&NSRunLoop
= [NSRunLoop
currentRunLoop];
&&&&[runLoop
runMode:NSDefaultRunLoopMode
beforeDate:[NSDate
distantFuture]];
this will not be executed
&&&&NSLog(@&while
这个时候我们可以看到主线程在执行完[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 之后被阻塞而没有执行下面的NSLog(@&while end&);同时,我们利用GCD,将这段代码放到一个后台线程中:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
&&&&&&&&NSLog(@&while
&&&&&&&&NSRunLoop
*subRunLoop
= [NSRunLoop
currentRunLoop];
&&&&&&&&[subRunLoop
runMode:NSDefaultRunLoopMode
beforeDate:[NSDate
distantFuture]];
&&&&&&&&NSLog(@&while
这个时候我们发现这个while循环会一直在执行;这是为什么呢?我们先将这两个RunLoop分别打印出来:
主线程的RunLoop
由于这个日志比较长,我就只截取了上面的一部分。
我们再看我们新建的子线程中的RunLoop,打印出来之后:
backGroundThreadRunLoop.png
从中可以看出来:我们新建的线程中:
我们看到虽然有Mode,但是我们没有给它soures,observer,timer,其实Mode中的这些source,observer,timer,统称为这个Mode的item,如果一个Mode中一个item都没有,则这个RunLoop会直接退出,不进入循环(其实线程之所以可以一直存在就是由于RunLoop将其带入了这个循环中)。下面我们为这个RunLoop添加个source:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
&&&&&&&&while
&&&&&&&&NSPort
&&&&&&&&NSLog(@&while
&&&&&&&&NSRunLoop
*subRunLoop
= [NSRunLoop
currentRunLoop];
&&&&&&&&[subRunLoop
addPort:macPort
forMode:NSDefaultRunLoopMode];
&&&&&&&&[subRunLoop
runMode:NSDefaultRunLoopMode
beforeDate:[NSDate
distantFuture]];
&&&&&&&&NSLog(@&while
&&&&&&&&NSLog(@&%@&,subRunLoop);
这样我们可以看到能够实现了和主线程中相同的效果,线程在这个地方暂停了,为什么呢?我们明天让RunLoop在distantFuture之前都一直run的啊?相信大家已经猜出出来了。这个时候线程被RunLoop带到‘坑’里去了,这个‘坑’就是一个循环,在循环中这个线程可以在没有任务的时候休眠,在有任务的时候被唤醒;当然我们只用一个while(1)也可以让这个线程一直存在,但是这个线程会一直在唤醒状态,及时它没有任务也一直处于运转状态,这对于CPU来说是非常不高效的。
小结:我们的RunLoop要想工作,必须要让它存在一个Item(source,observer或者timer),主线程之所以能够一直存在,并且随时准备被唤醒就是应为系统为其添加了很多Item
三、深入理解Perform Selector
我们先在主线程中使用下performselector:&br/&
(void)tryPerformSelectorOnMianThread{
performSelector:@selector(mainThreadMethod)
withObject:nil];
(void)mainThreadMethod{
NSLog(@&execute
%s&,__func__);
// print: execute -[ViewController mainThreadMethod]
这样我们在ViewDidLoad中调用tryPerformSelectorOnMianThread,就会立即执行,并且输出:print: execute -[ViewController mainThreadMethod];
和上面的例子一样,我们使用GCD,让这个方法在后台线程中执行
(void)tryPerformSelectorOnBackGroundThread{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
performSelector:@selector(backGroundThread)
onThread:[NSThread
currentThread]
withObject:nil
waitUntilDone:NO];
(void)backGroundThread{
NSLog(@&%u&,[NSThread
isMainThread]);
NSLog(@&execute
%s&,__FUNCTION__);
同样的,我们调用tryPerformSelectorOnBackGroundThread这个方法,我们会发现,下面的backGroundThread不会被调用,这是什么原因呢?
这是因为,在调用performSelector:onThread: withObject: waitUntilDone的时候,系统会给我们创建一个Timer的source,加到对应的RunLoop上去,然而这个时候我们没有RunLoop,如果我们加上RunLoop:
(void)tryPerformSelectorOnBackGroundThread{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
performSelector:@selector(backGroundThread)
onThread:[NSThread
currentThread]
withObject:nil
waitUntilDone:NO];
= [NSRunLoop
currentRunLoop];
这时就会发现我们的方法正常被调用了。那么为什么主线程中的perfom selector却能够正常调用呢?通过上面的例子相信你已经猜到了,主线程的RunLoop是一直存在的,所以我们在主线程中执行的时候,无需再添加RunLoop。
小结:当perform selector在后台线程中执行的时候,这个线程必须有一个开启的runLoop
四、一直”活着”的后台线程
现在有这样一个需求,每点击一下屏幕,让子线程做一个任务,然后大家一般会想到这样的方式:
@interface
ViewController
@property(nonatomic,strong)
*myThread;
@implementation
ViewController
(void)alwaysLiveBackGoundThread{
= [[NSThread
alloc]initWithTarget:self
selector:@selector(myThreadRun)
object:@&etund&];
self.myThread
[self.myThread
(void)myThreadRun{
NSLog(@&my
thread run&);
(void)touchesBegan:(NSSet&UITouch
*& *)touches
withEvent:(UIEvent
&&&&NSLog(@&%@&,self.myThread);
performSelector:@selector(doBackGroundThreadWork)
onThread:self.myThread
withObject:nil
waitUntilDone:NO];
(void)doBackGroundThreadWork{
&&&&NSLog(@&do
some work %s&,__FUNCTION__);
这个方法中,我们利用一个强引用来获取了后天线程中的thread,然后在点击屏幕的时候,在这个线程上执行doBackGroundThreadWork这个方法,此时我们可以看到,在touchesBegin方法中,self.myThread是存在的,但是这是为是什么呢?这就要从线程的五大状态来说明了:新建状态、就绪状态、运行状态、阻塞状态、死亡状态,这个时候尽管内存中还有线程,但是这个线程在执行完任务之后已经死亡了,经过上面的论述,我们应该怎样处理呢?我们可以给这个线程的RunLoop添加一个source,那么这个线程就会检测这个source等待执行,而不至于死亡(有工作的强烈愿望而不死亡):
(void)myThreadRun{
[[NSRunLoop
currentRunLoop]
addPort:[[NSPort
forMode:NSDefaultRunLoopMode];
[[NSRunLoop
currentRunLoop]
&&NSLog(@&my
thread run&);
这个时候再次点击屏幕,我们就会发现,后台线程中执行的任务可以正常进行了。
小结:正常情况下,后台线程执行完任务之后就处于死亡状态,我们要避免这种情况的发生可以利用RunLoop,并且给它一个Source这样来保证线程依旧还在
五、深入理解NSTimer
我们平时使用NSTimer,一般是在主线程中的,代码大多如下:
(void)tryTimerOnMainThread{
= [NSTimer
scheduledTimerWithTimeInterval:0.5
target:self&&&&&&
&&&&selector:@selector(timerAction)
userInfo:nil
repeats:YES];
(void)timerAction{
NSLog(@&timer
这个时候代码按照我们预定的结果运行,如果我们把这个Tiemr放到后台线程中呢?
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
&&&&NSTimer
= [NSTimer
scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(timerAction)
userInfo:nil
repeats:YES];
&&&&[myTimer
这个时候我们会发现,这个timer只执行了一次,就停止了。这是为什么呢?通过上面的讲解,想必你已经知道了,NSTimer,只有注册到RunLoop之后才会生效,这个注册是由系统自动给我们完成的,既然需要注册到RunLoop,那么我们就需要有一个RunLoop,我们在后台线程中加入如下的代码:
= [NSRunLoop
currentRunLoop];
&&&&[runLoop
这样我们就会发现程序正常运行了。在Timer注册到RunLoop之后,RunLoop会为其重复的时间点注册好事件,比如1:10,1:20,1:30这几个时间点。有时候我们会在这个线程中执行一个耗时操作,这个时候RunLoop为了节省资源,并不会在非常准确的时间点回调这个Timer,这就造成了误差(Timer有个冗余度属性叫做tolerance,它标明了当前点到后,容许有多少最大误差),可以在执行一段循环之后调用一个耗时操作,很容易看到timer会有很大的误差,这说明在线程很闲的时候使用NSTiemr是比较傲你准确的,当线程很忙碌时候会有较大的误差。系统还有一个CADisplayLink,也可以实现定时效果,它是一个和屏幕的刷新率一样的定时器。如果在两次屏幕刷新之间执行一个耗时的任务,那其中就会有一个帧被跳过去,造成界面卡顿。另外GCD也可以实现定时器的效果,由于其和RunLoop没有关联,所以有时候使用它会更加的准确,这在最后会给予说明。
六、让两个后台线程有依赖性的一种方式
给两个后台线程添加依赖可能有很多的方式,这里说明一种利用RunLoop实现的方式。原理很简单,我们先让一个线程工作,当工作完成之后唤醒另外的一线程,通过上面对RunLoop的说明,相信大家很容易能够理解这些代码:
(void)runLoopAddDependance{
self.runLoopThreadDidFinishFlag
NSLog(@&Start
a New Run Loop Thread&);
*runLoopThread
= [[NSThread
initWithTarget:self
selector:@selector(handleRunLoopThreadTask)
object:nil];
[runLoopThread
NSLog(@&Exit
handleRunLoopThreadButtonTouchUpInside&);
dispatch_async(dispatch_get_global_queue(0,
(!_runLoopThreadDidFinishFlag)
&&&&&&&&self.myThread
= [NSThread
currentThread];
&&&&&&&&NSLog(@&Begin
RunLoop&);
&&&&&&&&NSRunLoop
= [NSRunLoop
currentRunLoop];
&&&&&&&&NSPort
&&&&&&&&[runLoop
addPort:myPort
forMode:NSDefaultRunLoopMode];
&&&&&&&&[[NSRunLoop
currentRunLoop]
runMode:NSDefaultRunLoopMode
beforeDate:[NSDate
distantFuture]];
&&&&&&&&NSLog(@&End
RunLoop&);
&&&&&&&&[self.myThread
&&&&&&&&self.myThread
(void)handleRunLoopThreadTask
NSLog(@&Enter
Run Loop Thread&);
(NSInteger
++)
&&&&NSLog(@&In
Run Loop Thread, count = %ld&,
&&&&sleep(1);
// 错误示范
_runLoopThreadDidFinishFlag
// 这个时候并不能执行线程完成之后的任务,因为Run Loop所在的线程并不知道runLoopThreadDidFinishFlag被重新赋值。Run Loop这个时候没有被任务事件源唤醒。
// 正确的做法是使用 &selector&方法唤醒Run Loop。 即如下:
NSLog(@&Exit
Normal Thread&);
performSelector:@selector(tryOnMyThread)
onThread:self.myThread
withObject:nil
waitUntilDone:NO];
// NSLog(@&Exit Run Loop Thread&);
七、NSURLConnection的执行过程
在使用NSURLConnection时,我们会传入一个Delegate,当我们调用了[connection start]之后,这个Delegate会不停的收到事件的回调。实际上,start这个函数的内部会获取CurrentRunloop,然后在其中的DefaultMode中添加4个source。如下图所示,CFMultiplexerSource是负责各种Delegate回调的,CFHTTPCookieStorage是处理各种Cookie的。如下图所示:
NSURLConnection的执行过程
从中可以看出,当开始网络传输是,我们可以看到NSURLConnection创建了两个新的线程:com.apple.NSURLConnectionLoader和com.apple.CFSocket.private。其中CFSocket是处理底层socket链接的。NSURLConnectionLoader这个线程内部会使用RunLoop来接收底层socket的事件,并通过之前添加的source,来通知(唤醒)上层的Delegate。这样我们就可以理解我们平时封装网络请求时候常见的下面逻辑了:
(!_isEndRequest)
&&&&NSLog(@&entered
run loop&);
&&&&[[NSRunLoop
currentRunLoop]
runMode:NSDefaultRunLoopMode
beforeDate:[NSDate
distantFuture]];
NSLog(@&main
finished,task be removed&);
(void)connectionDidFinishLoading:(NSURLConnection
*)connection
&&_isEndRequest
这里我们就可以解决下面这些疑问了:
为什么这个While循环不停的执行,还需要使用一个RunLoop? 程序执行一个while循环是不会耗费很大性能的,我们这里的目的是想让子线程在有任务的时候处理任务,没有任务的时候休眠,来节约CPU的开支。
如果没有为RunLoop添加item,那么它就会立即退出,这里的item呢? 其实系统已经给我们默认添加了4个source了。
既然[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];让线程在这里停下来,那么为什么这个循环会持续的执行呢?因为这个一直在处理任务,并且接受系统对这个Delegate的回调,也就是这个回调唤醒了这个线程,让它在这里循环。
八、AFNetWorking中是如何使用RunLoop的?
在AFN中AFURLConnectionOperation是基于NSURLConnection构建的,其希望能够在后台线程来接收Delegate的回调。
为此AFN创建了一个线程,然后在里面开启了一个RunLoop,然后添加item
(void)networkRequestThreadEntryPoint:(id)__unused
@autoreleasepool
&&&&[[NSThread
currentThread]
setName:@&AFNetworking&];
&&&&NSRunLoop
= [NSRunLoop
currentRunLoop];
&&&&[runLoop
addPort:[NSMachPort
forMode:NSDefaultRunLoopMode];
&&&&[runLoop
*)networkRequestThread
&&&&static
*_networkRequestThread
&&&&static
dispatch_once_t
oncePredicate;
&&&&dispatch_once(&oncePredicate,
&&&&&&&&_networkRequestThread
= [[NSThread
initWithTarget:self
selector:@selector(networkRequestThreadEntryPoint:)
object:nil];
&&&&&&&&[_networkRequestThread
&&&&return
_networkRequestThread;
这里这个NSMachPort的作用和上文中的一样,就是让线程不至于在很快死亡,然后RunLoop不至于退出(如果要使用这个MachPort的话,调用者需要持有这个NSMachPort,然后在外部线程通过这个port发送信息到这个loop内部,它这里没有这么做)。然后和上面的做法相似,在需要后台执行这个任务的时候,会通过调用:[NSObject performSelector:onThread:..]来将这个任务扔给后台线程的RunLoop中来执行。
(void)start
[self.lock
isCancelled])
performSelector:@selector(cancelConnection)
onThread:[[self
networkRequestThread]
withObject:nil
waitUntilDone:NO
modes:[self.runLoopModes
allObjects]];
&&&&self.state
= AFOperationExecutingState;
performSelector:@selector(operationDidStart)
onThread:[[self
networkRequestThread]
withObject:nil
waitUntilDone:NO
modes:[self.runLoopModes
allObjects]];
[self.lock
GCD定时器的实现
(void)gcdTimer{
// get the queue
dispatch_queue_t
= dispatch_get_global_queue(0,
// creat timer
self.timer
= dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
// config the timer (starting time,interval)
// set begining time
dispatch_time_t
= dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(1.0
* NSEC_PER_SEC));
// set the interval
= (uint64_t)(1.0
* NSEC_PER_SEC);
dispatch_source_set_timer(self.timer,
dispatch_source_set_event_handler(self.timer,
the tarsk needed to be processed async
&&&&dispatch_async(dispatch_get_global_queue(0,
&&&&&&&&for
i++)
&&&&&&&&&&&&NSLog(@&gcdTimer&);
dispatch_resume(self.timer);
九、延伸阅读
http://chun.tips/blog//zou-jin-run-loopde-shi-jie-%5B%3F%5D-:shi-yao-shi-run-loop%3F/
/library/ios/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/i-CH16-SW1
/ios/70.html
http://blog.csdn.net/enuola/article/details/9163051
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11930次
排名:千里之外
转载:317篇
(1)(91)(51)(150)(36)}

我要回帖

更多关于 mc1.8.1如何联机 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信