ios4怎么调ios7小圆点点呢?............

送走了 2015,迎来了 2016,所谓新年新气象,大家有没有从本周推荐中感受到新气象?
或许是库克希望我们认为,尽管融合两个(或多个)系统对部分人来说很有吸引力,但这或...
游戏这块市场以及游戏这个产业,任谁也不能忽视。
即将到来的Galaxy S7和 S7 Edge两款旗舰机型的续航将得到大幅提升,并且将恢复防水功...
这将是 Xperia Z 旗舰系列中首款粉红色的手机,除了妹子外或许男生也会喜欢。
环形建筑上开始安装巨型玻璃,主体结构部分施工已经接近完成,第一款在新总部地下礼堂...
HomeKit 或许会在2016年里大有作为,当然,除了自身提高以外,还需要更多智能家居的支...
在2016年国际消费电子展上,美国智能手机厂商BLU宣布推出VIVO 5,VIVO XL智能手机。
群雄“逐鹿”,“天下”大乱,自从《逐鹿天下》在App Store上架之后,小编我就第一时...
近日,游戏开发商Hi-Rez Studios所制作的横版跑酷游戏《飞行斗士(Jetpack Fighter)...
说起游戏开发商King,可能许多玩家最熟悉的就莫过于他们所制作的热门休闲游戏《糖果粉...
意料之中,网易早在 2015 年 11 月份推出《功夫熊猫(官方正版)》的时候,就同时宣布...
随着时间的流逝,我们看动画片的时间越来越少了,但是很多形象都被搬到了游戏世界当中...
不管你是吹是黑,企鹅的《火影忍者-官方正版》没出之前就已经受到无数双眼睛在关注,...
武侠片作为具有“中国特色”的一种电影形式,经过了几代人孜孜不倦的努力后,终于被全...
那么多款Apple Watch配件,总有一款适合你。
体积不小,才 5000mAh 容量就做得这么大真的好吗?
广角、变焦、微距都有,镜头身上还有蔡司小蓝标,品质有保证。
虽然看起来很智能的样子,但如果iPhone被偷了可能就是双重悲剧了。
出门戴表再也不怕没电了,又能再跑几圈!
直接采用 USB Type-C 接口设计,这意味着可直接连接到最新的 12 英寸 MacBook 上使用...
看上去毫无违和感——除了机身变得很长以外,它就像一块外用的备用电池。
虽然充电效率可能没有那些厚重的无线充电手机壳那么高,但至少它不会增加手机负担,同...
IOS7.1,系统自带小圆点的的图怎么做,
注册时间 最后登录
在线时间1 小时 UID
主题帖子人气
小苹果, 积分 15, 距离下一级还需 35 积分
系统自带小圆点的美化,我把大小调整了,但是不是透明的,求大神教教我啊,
注册时间 最后登录
在线时间1 小时 UID
主题帖子人气
来人帮忙啊。。
注册时间 最后登录
在线时间446 小时 UID
主题帖子人气
透明以后你还能看见吗???
有钱好--有钱好--有钱真好--有钱真的好----有钱好--有钱好--有钱真好--有钱真的好
注册时间 最后登录
在线时间130 小时 UID
主题帖子人气
好像没看到这种插件
注册时间 最后登录
在线时间452 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
注册时间 最后登录
在线时间385 小时 UID
主题帖子人气
金券   ? 8303697
撸主谦虚搜索
注册时间 最后登录
在线时间1 小时 UID
主题帖子人气
透明以后你还能看见吗???
只是做图,不用全透明。吧图片背景做透明化。。
注册时间 最后登录
在线时间1 小时 UID
主题帖子人气
越狱了小圆点那破手势还用?
用来锁屏用。。。不知道什么插件好用。。
威锋旗下产品
Hi~我是威威!
沪ICP备号-1 丨 深公安网监备案号 5
增值电信业务经营许可证:
Powered by Discuz!Hot 提示:点击↑上方&蓝字&关注我!Cydia源
感觉Home键总是要坏的同学们!小圆点功能升级啦,妈妈再也不用担心我的学习啦!同样价格,从6个功能升级到最多8个功能,还能自定义每个按钮的功能!一个点顶过去五个点!
进入设置-通用-辅助功能-Assistive Touch,开启并进入自定顶层菜单
通过点击右下角的加减号,可以使按钮变成1个或者8个,不过要注意的是,如果已经有设置功能的按键,在删除后再添加,功能会被清除而不会保留。
点击单个按钮,可以从设置好的功能里面选择!以前截屏需要进入设备-更多-屏幕快照三个步骤,现在只需要点一次!
感觉棒棒哒,home 键再也不会坏了! 
 文章为作者独立观点,不代表微头条立场
的最新文章
每次新一代iPhone到来之前,市场中就充斥着各种传言。根据往年的惯例,大多数传言是相当不靠谱,但是也有许Hot 提示:点击↑上方"蓝字"关注我!Cydia源Hot 提示:点击↑上方"蓝字"关注我!Cydia源
日前,苹果公司宣布已经和中国银联达成合作苹果将主摄像头的像素从之前的800万提升到了1200万,以实现更加出色的成像效果,这一方面的改进是绝大部分喜欢摄影的果粉非常乐意看到的,尽管iPhone的摄影效果仍然无法跟单反相机相媲美。身边小伙伴新买了iPhone 6s之后,总想让别人知道他买了新手机!于是打电话要这样打!买手机壳要买透明的!我们知道,苹果在 iOS 9 中允许开发者为 Safari 浏览器制作广告拦截应用,这不仅让谷歌急了,近2013 年 7 月份美国专利商标局公布了苹果公司一项与固态电池充电技术相关的专利。固态电池属于低功率密16 岁到 30 岁的人,到底会花多少时间在我们的 iPhone 或者 iPad 这些移动设备上呢?根平时用iPhone浏览网页时总是自动弹出各种奇怪的广告,尤其是在使用蜂窝网络时,这样不仅降低Hot 提示:点击↑上方"蓝字"关注我!Cydia源粉丝们对新一代iPhone的期待从来就没消停过,这不,大家又开始猜测iPhone7会给我们什前一段时间网上测试iPhone初代到最新型号测试防水功能的视频,视频中已经证实iPhone所苹果iPhone从2007年面世至今,在全世界范围内赢取了许多消费者的心。今天,我们就来说一虽然现在已经是2015年了,但苹果和谷歌的入门手机仍然只有16GB。对于经常使用手机拍摄照片和视频、苹果向开发者发送电子邮件,宣布了苹果应用商店App Store应用的累积下载量已经超过了1Hot 提示:点击↑上方"蓝字"关注我!Cydia源Google Analytics 追踪相关访问数据发现,搭载 iOS 10
的设备在上月末Hot 提示:点击↑上方"蓝字"关注我!Cydia源Hot 提示:点击↑上方"蓝字"关注我!Cydia源
美国专利和商标局(USPTO)今天公布了一Hot 提示:点击↑上方"蓝字"关注我!Cydia源iPhone6s才出来不到两个月,下一代智能手机iPhoHot 提示:点击↑上方"蓝字"关注我!Cydia源
苹果最近更新版本的节奏似乎特别快,测试版本一个接Hot 提示:点击↑上方"蓝字"关注我!Cydia源
iOS 9 越狱工具发布还没有到一个月的Hot 提示:点击↑上方"蓝字"关注我!Cydia源Hot 提示:点击↑上方"蓝字"关注我!Cydia源没错,这些照片都是用iPhone 6拍的。嗯哼,这还是iHot 提示:点击↑上方"蓝字"关注我!Cydia源
iPad Pro究竟是个什么产品?解释Hot 提示:点击↑上方"蓝字"关注我!Cydia源
最近iPhone着实又火了一把,相信很多Hot 提示:点击↑上方"蓝字"关注我!Cydia源
凌晨苹果向开发者和公测用户推送了iOS Hot 提示:点击↑上方"蓝字"关注我!Cydia源Hot 提示:点击↑上方"蓝字"关注我!Cydia源
特工题材的电影一直是票房的保证,看着特工Hot 提示:点击↑上方"蓝字"关注我!Cydia源Hot 提示:点击↑上方"蓝字"关注我!Cydia源
最近,iPhone遭远程锁定的案例频发:Hot 提示:点击↑上方"蓝字"关注我!Cydia源
跟一个段子说的一样,老婆用上了iPhonHot 提示:点击↑上方"蓝字"关注我!Cydia源
尽管 iPad Pro 已在上周正式发售Hot 提示:点击↑上方"蓝字"关注我!Cydia源
近日,一则名为“京东双11预热,砍价0元拿Hot 提示:点击↑上方"蓝字"关注我!Cydia源一直有一个几乎所有机友都认同的说法:Android 是全Hot 提示:点击↑上方"蓝字"关注我!Cydia源
不少越狱用户想必还记得,在上个月苹果发布此前在iPhone6
Plus上曾有用户反馈动画掉帧,现在到了iPhone6s Plus似乎依然没有得到改善。那么,iPhone6s Plus掉帧怎么办呢?有什么办法能解决6s
Plus掉帧问题吗?Hot 提示:点击↑上方"蓝字"关注我!Cydia源
在线购物数据追踪公司Slice InteHot 提示:点击↑上方"蓝字"关注我!Cydia源图自暴走漫画。Hot 提示:点击↑上方"蓝字"关注我!Cydia源
苹果继续对 iOS 系统进行升级测试,这一Hot 提示:点击↑上方"蓝字"关注我!Cydia源
苹果上周发布了 iOS 9.1 正式版,对Hot 提示:点击↑上方"蓝字"关注我!Cydia源
自从10月起开始执行当月流量不清零政策以Hot 提示:点击↑上方"蓝字"关注我!Cydia源
盘古越狱团队去年横空出世,如今已经发展成为IAgame官方插件源: apt.so/9931994
插件不定时更新,需要什么插件留言。…… iPhone序列号查询,越狱。热门文章最新文章IAgame官方插件源: apt.so/9931994
插件不定时更新,需要什么插件留言。…… iPhone序列号查询,越狱。1847人阅读
在iOS4中使用代码块-基础知识&
&iOS4引入了一个新特性,支持代码块的使用,这将从根本上改变你的编程方式。代码块是对C语言的一个扩展,因此在Objective-C中完全支持。如果你学过Ruby,Python或Lisp编程语言,那么你肯定知道代码块的强大之处。简单的说,你可以通过代码块封装一组代码语句并将其当作一个对象。代码块的使用是一种新的编码风格,可以让你运用自如的使用iOS4中新增API。
&&&&我们先来看两个在iOS4中使用代码块的例子(你很有可能已经见过):view animations 和enumeration
使用代码块的例子
&&&& 第一个例子,假设我们创建一个纸牌游戏,需要展现纸牌被派发到玩家面前的动画效果。幸运的是通过UIKit框架可以很容易的实现一个动画效果。但是最终是什么样的动画是由你的程序决定的。你可以在代码块中指定动画的内容然后再将代码块传给animateWithDuration:animations:方法,像下面这样:
[UIView animateWithDuration:2.0
&&&&animations:^ {
&&&&&&&&self.cardView.alpha = 1.0;
&&&&&&&&self.cardView.frame = CGRectMake(176.0, 258.0, 72.0, 96.0);
&&&&&&&&self.cardView.transform = CGAffineTransformMakeRotation(M_PI);
&&&&当这个动画代码块执行时,我们的纸牌会展现三种方式的动画:改变它的alpha值从而淡入显示,改变它的位置到右下角(玩家的位置),以及自转180度(为了使其效果更好)。
第二个代码块的例子是迭代一个纸牌的集合,并打印其名字和在集合里的索引值。
你可以通过使用for循环来达到目的,但是在iOS4中NSArray类有一个使用了代码块的方便方法:enumerateObjectsUsingBlock:。下面是如何使用它:
NSArray *cards = [NSArray arrayWithObjects:@&Jack&, @&Queen&, @&King&, @&Ace&, nil];
[cards enumerateObjectsUsingBlock:^(id object, NSUInteger index, BOOL *stop) {
&&&&NSLog(@&%@ card at index %d&, object, index);
&&&&这个代码块使用了三个参数:数组中的一个对象,该对象的索引,以及一个标识迭代是否结束的标志。我们稍候再对其进一步探讨。enumerateObjectsUsingBlock: 这个方法会将集合中的每一个元素传入相应的参数并调用代码块中的方法。
&&&&因此在你的mac和iOS程序中使用代码块的优势是:它允许你附加任意的代码到苹果官方提供的方法上。尽管在概念上与代理相似,但是在方法中使用简短的内联代码块往往更加方便,更加优雅。
&&&&这是一个好的开始,但重要的是要明白它内部的处理。当我学习新东西的时候,我喜欢先将其分为一个个简单的部分,了解它们如何工作,然后再将它们组装到一块,这样我会对自己写的代码以及快速解决出现的问题充满信心。因此,让我们先回头学习下如何声明和调用简单的代码块。
代码块的基本概念
&&&&一个代码块可以简单看作是一组可执行的代码。例如,下面是一个打印当前日期和时间的代码块:
&&&&NSDate *date = [NSDate date];
&&&&NSLog(@&The date and time is %@&, date);
&&&&插入符号(^)声明一个代码块的开始,一对大括号{}构成了代码块的体部。你可以认为代码块与一个匿名函数类似。那么,如果是一个匿名的函数,我们该怎么调用这个代码块呢?最常见使用代码块的方式是将其传入方法中供方法回调,就像之前我们已经见到了view animati***** 和enumeration。另一种使用代码块的方式是将其赋予代码块变量,然后可使用该变量来直接调用代码块。以下是如何声明我们的代码块并将它赋予代码块变量now:
void (^now)(void) = ^ {
&&&&NSDate *date = [NSDate date];
&&&&NSLog(@&The date and time is %@&, date);
&&&&声明一个块变量的语法需要一些时间适应,这才有趣。如果你使用过函数指针,代码块变量与其类似。在上面代码等号右边是我们已经介绍过的代码块。等号左边我们声明了一个代码块变量now。
&&&&代码块变量之前有^符号并被小括号包着,代码块变量有类型定义的。因此,上图中的now变量可以应用任何无参,无返回值的代码块。我们之前声明的代码块符合这要求,,所以我们可以放心的把它分配给now变量。
&&&&只要有一个代码块变量,并在其作用域范围内,我们就可以像调用函数一样来调用它。下面是如何调用我们的代码块:
&&&&你可以在C函数或者Objective-c方法中声明代码块变量,然后在同一作用域内调用它,就像我们前面说明那样。当代码块执行时,它打印当前的日期和时间。目前为止,进展顺利。
代码块是闭包
&&&&如果这就是代码块的全部的话,那么他与函数是完全相同的。但事实是代码块不仅仅是一组可执行的代码。代码块能够捕捉到已声明的同一作用域内的变量,同时由于代码块是闭包,在代码块声明时就将使用的变量包含到了代码块范围内。为了说明这一点,让我们改变一下前面的例子,将日期的初始化移到代码块之外。
NSDate *date = [NSDate date];
void (^now)(void) = ^ {
&&&&NSLog(@&The date and time is %@&, date);
&&&&当你第一次调用这个代码块的时候,它与我们之前的版本结果完全一致:打印当前的日期和时间。但是当我们改变日期后再调用代码块,那么就会有显著的不同了,
date = [NSDate date];
&&&&尽管我们在调用代码块之前改变了日期,但是当代码块调用时仍然打印的是之前的日期和时间。就像是日期在代码块声明时停顿了一样。为什么会这样呢,当程序执行到代码块的声明时,代码块对同一作用域并且块内用到的变量做一个只读的备份。你可以认为变量在代码块内被冻结了。因此,不论何时当代码块被调用时,立即调用或5秒钟之后,只要在程序退出之前,它都是打印最初的日期和时间。
&&&&事实上,上面那个展示代码块是闭包的例子并不十分完善,毕竟,你可以将日期作为一个参数传入到代码块中(下面讲解)。但是当你将代码块在不同方法间传递时闭包的特性就会变得十分有用,因为它里面的变量是保持不变的。
代码块参数
&&&&就像函数一样,代码块可以传入参数和返回结果。例如,我们想要一个能够返回指定数的三倍的代码块,下面是实现的代码块:
^(int number) {
&&&&return number * 3;
&&&&为代码块声明一个变量triple,如下:
int (^triple)(int) = ^(int number) {
&&&&return number * 3;
&&&&上面说过,我们需要熟悉等号左边声明代码块变量的语法。现在让我们从左到右分开来说明:
最左边的int是返回值类型,中间是小括号包围插入符号^及代码块变量的名字,最后又一个小括号,包围着参数的类型(上面例子中只有一个int参数)。等号右边的代码块声明必须符合左侧的定义。有一点要说明的是,为了方便,可以不声明代码块的返回类型,编译器会从返回语句中做出判断。
&&&&要调用这个代码块,你需要传入一个需要乘3的参数,并接受返回值,像这样:
int result = triple(2);
&&&&下面你将知道如何声明并创建一个需要两个int型参数,将它们相乘然后返回结果的代码块:
int (^multiply)(int, int) = ^(int x, int y) {
&&&&return x *
&&&&这是如何调用这个代码块:
int result = multiply(2, 3);
&&&&声明代码块变量使我们有机会探讨代码块类型以及如何调用。代码块变量类似函数指针,调用代码块与调用函数相似。不同于函数指针的是,代码块实际上是Objective-C对象,这意味着我们可以像对象一样传递它们。
调用代码块的方法
&&&&在实际中,代码块经常被作为参数传入方法中供其回调。当把代码块作为一个参数时,相比分配一个代码块变量,更通常的做法是作为内联代码块。例如,我们之前看到的例子:view animations 和enumeration。
&&&&苹果官方已经增加了一些使用代码块的方法到他们的框架中。你也可以写一些使用代码块的API了。例如,我们要创建一个Worker类的使用代码块的类方法,该方法重复调用代码块指定的次数,并处理代码块每次返回的结果。下面是我们使用内联代码块调用这个方法,代码块负责返回1到10的每个数的三倍。
[Worker repeat:10 withBlock:^(int number) {
&&&&return number * 3;
&&&&这个方法可以将任何接受一个int型参数并返回一个int型结果的代码块作为参数,如果想得到数字的二倍,只需要改变传入方法的代码块。
到你动手的时候了
&&&&那么你将如何去实现上面我们使用的 repeat:withBlock:这个方法,考虑一下,我们将在给出分解。在此期间,通过调用enumerateKeysAndObjectsUsingBlock: 方法打印一个NSDictiobary的键和值来练习使用代码块:
NSDictionary *cards =&
&&&&[NSDictionary dictionaryWithObjectsAndKeys:@&Queen&,& @&card&,&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@&Hearts&, @&suit&,&
& & & & & & & & & & & & & & & & & & & & & & & &@&10&,&&&& @&value&, nil];
在iOS4中使用代码块-代码块设计
在本系列的,我们学会了如何声明和调用基本的Objective-C代码块。动机是为了了解如何有效的使用iOS4提供的使用代码块作为参数的API。在这一部分我们将重点转向写我们自己的使用代码块的方法。通过理解在自己的代码中如何使用代码块,你将会掌握一种新的设计技术。而且你可能会意识到,代码块会使你的代码易于阅读和维护。
编写使用代码块的方法
&&&&在第一部分我们留下了一个任务:写一个Work类的调用代码块的类方法,并且重复调用代码块指定的次数,还要处理每次代码块的返回值。如果我们想要得到1到5的三倍的话,那么下面是我们该如何调这个带有内联代码块的方法:
[Worker repeat:5 withBlock:^(int number) {
&&&&return number * 3;
&&&&我经常这样设计一个类,首先写代码调用一个虚构的方法,这也是在提交之前一种形成API的简单方式,一旦认为这个方法调用正确,我就去实现这个方法。这样,那个方法的名字是repeat:withBlock:,我认为不合适(我知道在第一部分是叫这个名字,但我已经改变注意了)。这个名字容易使人混淆,因为该方法实际上并不是重复做相同的事情。这个方法从1迭代到指定的次数,并处理代码块的返回。所以让我们开始正确的重命名它:
[Worker iterateFromOneTo:5 withBlock:^(int number) {
&&&&return number * 3;
&&&&我对这个使用两个参数的方法的名字iterateFromOneTo:withBlock:很满意,一个int型参数表示调用代码块的次数和一个要被调用的代码块参数。现在让我们去实现这个方法。
&&&&对于初学者,我么该如何声明这个 iterateFromOneTo:withBlock:方法呢?首先我们需要知道所有参数的类型,第一个参数很容易,是个int类型;第二个参数是一个代码块,代码块是有返回类型的。在这个例子中,这个方法可以接受任何有一个int型参数并返回int型结果的代码块作为参数。下面是实际的代码块类型:
int (^)(int)
&&&&已经有了方法的名字和它的参数类型,我们就可以声明这个方法了。这是Worker类的类方法,我们在worker.h中声明它:
@interface Worker : NSObject {
+ (void)iterateFromOneTo:(int)limit withBlock:(int (^)(int))
&&&&第一眼看去,代码块参数不容易理解。有个要记住诀窍是:在Objective-C中所有的方法参数有两个部分组成。被括起来的参数类型以及参数的名称。这个例子中,参数的要求是一个是int型和一个是int(^)(int)型的代码块(你可以为参数命名为任意的名字,不一定非得是block)。这个方法的实现是在Worker.m文件文件中,比较简单:
#import &Worker.h&
@implementation Worker
+ (void)iterateFromOneTo:(int)limit withBlock:(int (^)(int))block {
&&&&for (int i = 1; i &= i++) {
&&&&&&&&int result = block(i);
&&&&&&&&NSLog(@&iteration %d =& %d&, i, result);
&&&&方法通过一个循环来每次调用代码块,并打印出代码块的返回结果。记住一旦我们在作用域内有一个代码块变量,那么就可以像函数一样使用它。在这里代码块参数就是一个代码块变量。因此,当执行block(i)时就会调用传入的代码块。当代码块返回结果后会继续往下执行。现在我们可以使用内联代码块的方式调用iterateFromOneTo:withBlock:方法,像这样:
[Worker iterateFromOneTo:5 withBlock:^(int number) {
&&&&return number * 3;
我们也可以不使用内联代码块的方式,传入一个代码块变量作为参数:
int (^tripler)(int) = ^(int number) {
&&&&return number * 3;
[Worker iterateFromOneTo:5 withBlock:tripler];
不论那种方式,我们得到的输出如下:
iteration 1 =& 3
iteration 2 =& 6
iteration 3 =& 9
iteration 4 =& 12
iteration 5 =& 15
&&&&当然我们可以传入进行任何运算的代码块。想要得到数字的平方吗?没问题,只要传入一个不同的代码块:
[Worker iterateFromOneTo:5 withBlock:^(int number) {
&&&&return number *
现在我们的代码是可以运行的,下面将代码稍微整理下吧。
善于使用Typedef
&&&&匆忙的声明代码块的类型容易混乱,即使在这个简单的例子中,函数指正的语法还是有许多不足之处:
+ (void)iterateFromOneTo:(int)limit withBlock:(int (^)(int))
&&&&试想代码块要使用多个参数,并且有些参数是指针类型,这样的话你几乎需要完全重写你的代码。为了提高可读性和避免在.h和.m中出项重复,我们可以使用typedef修改Worker.h文件:
typedef int (^ComputationBlock)(int);
@interface Worker : NSObject {
+ (void)iterateFromOneTo:(int)limit withBlock:(ComputationBlock)
&&&&typedef是C语言的一个关键字,其作用可以理解为将一个繁琐的名字起了一个昵称。在这种情况下,我们定义一个代码块变量ComputationBlock,它有一个int型参数和一个int型返回值。然后,我们定义iterateFromOneTo:withBlock:方法时,可以直接使用ComputationBlock作为代码块参数。同样,在Worker.m文件,我们可以通过使用ComputationBlock简化代码:
#import &Worker.h&
@implementation Worker
+ (void)iterateFromOneTo:(int)limit withBlock:(ComputationBlock)block {
&&&&for (int i = 1; i &= i++) {
&&&&&&&&int result = block(i);
&&&&&&&&NSLog(@&iteration %d =& %d&, i, result);
&&&&嗯,这样就好多了,代码易于阅读,没有在多个文件重复定义代码块类型。事实上,你可以使用ComputationBlock在你程序的任何地方,只要import “Worker.h”,你会碰到类似的typedef在新的iOS4的API中。例如,ALAssetsLibrary类定义了下面的方法:
- (void)assetForURL:(NSURL *)assetURL&&&&&&
&&&&&&&&resultBlock:(ALAssetsLibraryAssetForURLResultBlock)resultBlock&
&&&&&&&failureBlock:(ALAssetsLibraryAccessFailureBlock)failureBlock
&&&&这个方法调用两个代码块,一个代码块时找到所需的资源时调用,另一个时没找到时调用。它们 的 typedef如下:
typedef void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *asset);
typedef void (^ALAssetsLibraryAccessFailureBlock)(NSError *error);
&&&&然后在你的程序中可以使用ALAssetsLibraryAssetForURLResultBlock和ALAssetsLibraryAccessFailureBlock去表示相应的代码块变量。
&&&&我建议在写一个使用代码块的公用方法时就用typedef,这样有助于你的代码整洁,并可以让其他开发人员方便使用。
再来看一下闭包
&&&&你应该还记得代码块是闭包,我们简要的讲述一下在第一部分提及的闭包。在第一部分闭包的例子并不实用,而且我说闭包在方法间传递时会变得特别有用。现在我们已经知道如何写一个实用代码块的方法,那么就让我们分析下另一个闭包的例子:
int multiplier = 3;
[Worker iterateFromOneTo:5 withBlock:^(int number) {
&&&&return number *
&&&&我们使用之前写的iterateFromOneTo:withBlock:方法,有一点不同的是没有将要得到的倍数硬编码到代码块中,这个倍数被声明在代码块之外,为一个本地变量。该方法执行的结果与之前一致,将1到5之间的数乘3:
iteration 1 =& 3
iteration 2 =& 6
iteration 3 =& 9
iteration 4 =& 12
iteration 5 =& 15
&&&&这个代码的运行是一个说明闭包强大的例子。代码打破了一般的作用域规则。实际上,在iteratefromOneTo:withBlock:方法中调用multiplier变量,可以把它看作是本地变量。
&&&&记住,代码块会捕捉周围的状态。当一个代码块声明时它会自动的对其内部用到的变量做一个只读的快照。因为我们的代码块使用了multiplier变量,这个变量的值被代码块保存了一份供之后使用。也就是说,multiplier变量已经成为了代码块状态啊的一部分。当代码块被传入到iterateFromOneTo:withBlock:方法,快的状态也传了进去。
&&&&好吧,如果我们想在代码块的内部改变multiplier变量该怎么办?例如,代码块每次被调用时要让multiplier变为上一次计算的结果。你可能会试着在代码块里直接改变multiplier变量,像这样:
int multiplier = 3;
[Worker iterateFromOneTo:5 withBlock:^(int number) {
&&&&multiplier = number *
&&&&& // compile error!
&&&&这样的话是通不过编译的,编译器会报错“Assignment of read-only variable 'mutilplier'”。这是因为代码块内使用的是变量的副本,它是堆栈里的一个常量。这些变量在代码块中是不可改变的。
&&&&如果你想要修改一个在块外面定义,在块内使用的变量时,你需要在变量声明时增加新的前缀_block,像这样:
__block int multiplier = 3;
[Worker iterateFromOneTo:5 withBlock:^(int number) {
&&&&multiplier = number *
NSLog(@&multiplier& =& %d&, multiplier);
这样代码可以通过编译,运行结果如下:
iteration 1 =& 3
iteration 2 =& 6
iteration 3 =& 18
iteration 4 =& 72
iteration 5 =& 360
multiplier& =& 360
&&&&要注意的是代码块运行之后,multiplier变量的值已经变为了360。换句话说,代码块内部修改的不是变量的副本。声明一个被_block修饰的变量是将其引用传入到了代码块内。事实上,被_block修饰的变量是被所有使用它的代码块共享的。这里要强调的一点是:_block不要随便使用。在将一些东西移入内存堆中会存在边际成本,除非你真的确定需要修改变量,否则不要用_block修饰符。
编写返回代码块的方法
&&&&有时我们会需要编写一个返回代码块的方法。让我先看一个错误的例子:
+ (ComputationBlock)raisedToPower:(int)y {
&&&&ComputationBlock block = ^(int x) {
&&&&&&&&return (int)pow(x, y);
&&&&& // Don't do this!
&&&&这种方法简单的创建了一个计算y的x次幂的代码块然后返回它。它使用了我们之前通过typedef使用的ComputationBlock。下面是我们对所返回代码块的期望效果:
ComputationBlock block = [Worker raisedToPower:2];
block(3);& // 9
block(4);& // 16
block(5);& // 25
&&&&在上面的例子中,我们使用的得到代码块,传入相应的参数,它应该会返回传入值的平方。但是当我们运行它时,会得到运行时错误”EXC_BAD_ACCESS”。
&&&&怎么办?解决这个问题的关键是了解代码块是怎么分配内存的。代码块的生命周期是在栈中开始的,因为在栈中分配内存是比较块的。是栈变量也就意味着它从栈中弹出后就会被销毁。方法返回结果就会发生这样的情况。
&&&&回顾我们的raisedToPower:方法,可以看到在方法中创建了代码块并将它返回。这样创建代码块就是已明确代码块的生存周期了,当我们返回代码块变量后,代码块其实在内存中已经被销毁了。解决办法是在返回之前将代码块从栈中移到堆中。这听起来很复杂,但是实际很简单,只需要简单的对代码块进行copy操作,代码块就会移到堆中。下面是修改后的方法,它可以满足我们的预期:
+ (ComputationBlock)raisedToPower:(int)y {
&&&&ComputationBlock block = ^(int x) {
&&&&&&&&return (int)pow(x, y);
&&&&return [[block copy] autorelease];
&&&&注意我们使用了copy后就必须跟一个autorelease从而平衡它的引用计数器,避免内存泄露。当然我们也可以在使用代码块之后将其手动释放,不过这就不符合谁创建谁释放的原则了。你不会经常需要对代码块进行copy操作,但是如果是上面所讲的情况你就需要了,这点请留意。
将所学的整合在一起
&&&&那么,让我们来把所学的东西整合为一个更实际点的例子。假设我们要设计一个简单的播放电影的类,这个类的使用者希望电影播放完之后能够接受一个用于展现应用特定逻辑的回调。前面已经证明代码块是处理回调很方便的方法。
让我们开始写代码吧,从一个使用这个类的开发人员的角度来写:
MoviePlayer *player =&
&&&&[[MoviePlayer alloc] initWithCallback:^(NSString *title) {
&&&&&&&&NSLog(@&Hope you enjoyed %@&, title);
[player playMovie:@&Inception&];
&&&&可以看出我们需要MoviePlayer类,他有两个方法:initWithCallback:和playMovie:,初始化的时候接受一个代码块,然后将它保存起来,在执行playMovie:方法结束后再调用代码块。这个代码块需要一个参数(电影的名字),返回void类型。我们对回调的代码块类型使用typedef,使用property来保存代码块变量。记住,代码块是对象,你可以像实例变量或属性一样使用它。这里我们将它当作属性使用。下面是MoviePlayer.h:
typedef void (^MoviePlayerCallbackBlock)(NSString *);
@interface MoviePlayer : NSObject {
@property (nonatomic, copy) MoviePlayerCallbackBlock callbackB
- (id)initWithCallback:(MoviePlayerCallbackBlock)&
- (void)playMovie:(NSString *)
下面是MoviePlayer.m:
#import &MoviePlayer.h&
@implementation MoviePlayer
@synthesize callbackB
- (id)initWithCallback:(MoviePlayerCallbackBlock)block {
&&&&if (self = [super init]) {
&&&&&&&&self.callbackBlock =
- (void)playMovie:(NSString *)title {
&&&&// play the movie
&&&&self.callbackBlock(title);
- (void)dealloc {
&&&&[callbackBlock release];
&&&&[super dealloc];
&&&&在initWithCallback:方法中将要使用的代码块声明为callbackBlock属性。由于属性被声明为了copy方式,代码块会自动进行copy操作,从而将其移到堆中。当playMovie:方法调用时,我们传入电影的名字作为参数来调用代码块。
&&&&现在我们假设一个开发人员要在程序中使用我们的MoviePlayer类来管理一组你打算观看的电影。当你看完一部电影之后,这部电影就会从组中移除。下面是一个简单的实现,使用了闭包:
NSMutableArray *movieQueue =&
&&&&[NSMutableArray arrayWithObjects:@&Inception&,&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@&The Book of Eli&,&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&@&Iron Man 2&,&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&nil];
MoviePlayer *player =&
&&&&[[MoviePlayer alloc] initWithCallback:^(NSString *title) {
&&&&&&&&[movieQueue removeObject:title];
for (NSString *title in [NSArray arrayWithArray:movieQueue]) {
&&&&[player playMovie:title];
&&&&请注意代码块使用了本地变量movieQueue,它会成为代码块状态的一部分。当代码块被调用,就会从数组movieQueue中移除一个电影,尽管此时数组是在代码块作用域之外的。当所有的电影播放完成之后,movieQueue将会是一个空数组。下面是一些需要提及的重要事情:
1、movieQueue变量是一个数组指针,我们不能修改它的指向。我们修改的是它指向的内容,因此不需要使用_block修饰。
2、为了迭代movieQueue数组,我们需要创建一个它的copy,否则如果我们直接使用movieQueue数组,就会出现在迭代数组的同事还在移除它的元素,这会引起异常。
3、如果不使用代码块,我们可以声明一个协议,写一个代理类,并注册这个代理作为回调。很明显该例子使用内联代码块更方便。
4、在不改变MoviePlayer类的前提下可以给他增加新功能。比如另一个开发者可以在看完一部电影后将其分享到twitter或对电影进行评价等。
接下来做什么呢
这是这个系列的结束,谢谢您的阅读。关于代码块的知识还有很多,当然我们所学的已经够平常的使用了。如果你想对其做深入研究,我推荐以下资源:
A Short Practical Guide to Blocks by Apple
Blocks Programming Topics by Apple
Block Basics by Bill Bumgarner
Blocks Tips & Tricks by Bill Bumgarner
Friday Q&A: Blocks by Mike Ash
How blocks are implemented (and the c*****equences) by Matt Gallagher
Language Specification for Blocks
WWDC Session 206 - Introducing Blocks and Grand Central Dispatch on iPhone
&&&&作为最后的一些提示,我希望你已经明白代码块是怎么提供了一种不同编码风格的,并且在你的程序设计中使用它。尝试着使用代码块,期待你的评论。
祝你愉快!
(Thanks to Matt Drance (@drance) and Daniel Steinberg (@dimsumthinking) for reviewing drafts of this article.)&&
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:375763次
积分:4544
积分:4544
排名:第3506名
原创:83篇
转载:68篇
评论:177条
(1)(7)(2)(2)(7)(5)(3)(4)(3)(6)(7)(4)(2)(6)(7)(4)(5)(2)(13)(2)(4)(1)(3)(1)(1)(1)(2)(1)(43)(1)(1)}

我要回帖

更多关于 ios9.1怎么设置小圆点 的文章

更多推荐

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

点击添加站长微信