首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

《Android和PHP开发最佳实践》一2.9 Android动画效果

2.9 Android动画效果 适当地使用动画效果可以很好地提升Android应用或游戏的操作体验。目前Android系统支持的动画效果主要有两种,即逐帧动画(Frame Animation)和补间动画(Tween Animation)。虽然,在Android 3.0以后的版本中还引入了新的动画系统,但是目前最主流的动画效果还是这两种。 2.9.1 逐帧动画(Frame Animation) 逐帧动画类似于GIF动画图片,即按照顺序播放图片。我们通常会在Android项目的res/drawable/目录下面定义逐帧动画的XML模板文件。编码的时候,需要在动画模板文件的标签中依次放入需要播放的图片,并设置好播放的间隔时间,如代码清单2-34所示。代码清单 2-34 <animation-list xmlns:android="

优秀的个人博客,低调大师

《企业级ios应用开发实战》一3.4 KVO模型

3.4 KVO模型 KVO(key-value observer,“键-值”观察)模型是Cocoa绑定技术中常用的一种编程模型,它可以使一个对象在属性值发生变化时主动通知另一个对象并触发相应的方法。与NSNotification 不同,KVO没有所谓的中心对象来为所有观察者提供变化通知。当“被观察者”对象状态发生变化时,通知被直接发送至“观察者”对象,如图3-1所示。 在图3-1中,观察者是aButton,被观察者是modelObject。aButton是一个按钮控件,它是一个UI对象,有一个BOOL型的enabled属性,表示按钮是否可被点击。modelObject对象是一个模型对象,它没有可以呈现给用户的界面,同样,它有一个BOOL属性selected。通过KVO模型,modelObject的selected属性可以绑定到UIButton的enabled属性。即当modelObject的selected属性发生变化时(这是可以被编程的),KVO会主动通知aButton这种改变,因此按钮的外观随之可发生相应的呈现。比如由不可点击的灰色改变为可点击的着色状态。KVO是一种很有用的绑定技术(Cocoa还提供另外一种绑定技术:Dynamic bingding)。而且它是由被观察的对象主动通知观察者的,并不需要经过一个统一的通知中心(如后面章节介绍的通知技术所述),它的执行效率和适用场景要更佳。为了实现KVO,你需要进行如下操作:注册观察者。所谓观察者即对象状态变化时需要通知的对象。接收变更通知。接收变更通知主要是让观察者实现指定方法,在指定方法中,你可以接收到对象状态变更的消息,并在方法中进行处理。取消所注册的观察者。观察者处理完状态变更消息之后,需要取消原先的注册状态。 3.4.1 注册KVO 对象要将自己注册为观察者,必须发送一个addObserver:forKeyPath:options:context:消息至被观察对象: [account addObserver:inspector forKeyPath:@"name" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL]; 以上例子将inspector对象注册为account对象的观察者,并表明观察者将对名为“name” 的属性变更感兴趣。forKeyPath参数“name”注明了需要观察的属性的关键路径KeyPath。关键路径KeyPath实际是一个字符串,用于表示某个属性,你可以直接用属性名。但如果某属性是一个对象,则KeyPath可以用“.”语法的形式表示对象成员,如“account.name”。options参数注明了对该属性的何种状态感兴趣。NSKeyValueObservingOptionNew表示属性在变更后的新值,NSKeyValueObservingOptionOld表示属性未改变之前的值。以上例子中的option参数设置表明,当name属性变更时,会将这两个值以NSDictionary的方式(即change参数)提交给观察者,观察者可以从NSDictionary中以键-值对的方式检索到这两个值。context参数用于传递一个对象,该对象(或指针)会在属性变化时通过变更通知传递给观察者(通过context参数)。移除观察者的注册,使用方法removeObserver forKeyPath: [subject removeObserver:observer forKeyPath:@"name"]; 3.4.2 接收变更通知 观察者要想收到对象的属性变更通知,需要实现方法observeValueForKeyPath:ofObject: change:context:,并在其中进行通知的处理。例如: - (void)observeValueForKeyPath:(NSString )keyPath ofObject:(id)object change:(NSDictionary )change context:(void )context { NSLog(@"%@",keyPath); if ([keyPath isEqual:@"name"]) { NSLog(@"name is changed:%@", [change objectForKey:NSKeyValueChangeNewKey]); }else [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } 3.4.3 发送变更通知 NSObject支持两种属性变更通知,一种是自动变更通知,一种是手动变更通知。一般情况下,使用自动变更通知则更为简单,因此我们主要介绍自动变更通知。1.自动变更通知要使用自动变更通知,需要实现被观察者的 automaticallyNotifiesObserversForKey方法,在此方法中明确说明需要使用自动变更通知的属性。对于需要使用自动变更通知的属性,返回YES,如下代码所示: + (BOOL) automaticallyNotifiesObserversForKey:(NSString)key { // 对于属性name ,使用自动通知 if ([key isEqualToString:@"name"]) { return YES; } // 确保调用了父类的automaticallyNotfiesObserversForKey方法 return [super automaticallyNotifiesObserversForKey:key]; } 然后,在name属性发生变化的时候通知观察者,比如调用以下语句之一: subject.name=newName; [subject setValue:newName forKey:@"name"]; [subject setValue:newName forKeyPath:@"name"]; 如果属性是集合类型,则可以使用方法mutableSetValueForKey来支持以下集合方法导致的自动变更通知:添加:insertObject:InKey:或者insertObject:AtIndex:替换:replaceObject:InKey:或者replaceObject:AtIndex:删除:removeObjectFromKey:或者removeObjectAtIndex:2.手动变更通知对于手动变更通知,除了需要在automaticallyNotifiesObserversForKey:方法中将要使用的手动变更通知返回NO外,还需要 在改变值之前调用willChangeValueForKey:并在更改它之后调用didChangeValueForKey:。为了便于你理解KVO模型,我做了一个示例程序,放在光盘“source/第3章/TestKVO”文件夹,它使用了本节所介绍的知识点,可供参考和学习。

优秀的个人博客,低调大师

《Android和PHP开发最佳实践 》一3.3 使用JSON通信

3.3 使用JSON通信 实际上,第1章中介绍如何结合Android和PHP学习时,我们就曾经提到过JSON协议,本节我们就来学习一下这个协议的基本内容。JSON是JavaScript对象表示法(JavaScript Object Notation)的简称,JSON协议源自JavaScript脚本语言的对象持久化表示方法,由于这种表示法比较简单易懂,而且传输的数据也比较小巧(相对于XML来说应该算是非常小巧了),因此,近年来被广泛地用于互联网应用的数据封装。首先,我们来学习一下JSON协议的数据表示方法。在JSON协议中,最基本的数据结构只有两种。第一种是数组结构,该结构类似于PHP中的列表数组,结构如下。 ["james","iris"] 第二种是对象结构,该结构非常类似于PHP中的散列数组,结构如下。 {"id":1,"name":

优秀的个人博客,低调大师

《企业级ios应用开发实战》一3.5 块编程

3.5 块编程 C语言的运行时特性中包括了块,标准C工作组的 N1370: Apple’s Extensions to C 中(其中也包括垃圾回收)对块进行了定义。作为C语言的扩展,Objective-C在OSX 10.6及iOS 4.0以后支持块语法。块运行时也会被集成到LLVM的compiler-rt子项目存储库中。 3.5.1 块的特点 一些面向对象的动态语言如ruby、groovy,都提供了对块的支持(在groovy中,块被称作为闭包“closure”)。块是用一对{}括号括起来的多个语句的集合。类似于函数,但不同于函数,可以把块作为表达式或变量的一部分,或者作为参数传递。在作为参数传递块时,代码被作为数据的一部分进行传递。块具有以下特征:同函数一样,有类型化参数列表。有返回结果或者要申明返回类型。能获取同一作用域(与块所在同一作用域)内的状态。可以修改同一作用域的状态(变量)。与同一范围内的其他块同享变量。在作用域释放后能继续共享和改变同一范围内的变量。除以上特点外,甚至可以复制块并传递到其他后续执行的线程,编译器和运行时负责把所有块引用的变量保护在所有块的拷贝的生命周期内。当然,这已经超出了本章的范围,可以参考苹果官方文档来了解这些内容。 3.5.2 Objective-C 中的块 对于C和C++,块是变量,但对于Objective-C,块仍然是对象。下面简单介绍Objective-C中的块。1.块变量声明用^操作符声明一个块变量的开始,分号表示块结束,如下代码所示: int multiplier = 7; int (^myBlock)(int) = ^(int num) { return num multiplier; }; 块语法比较奇怪,块变量声明的解释如图3-2所示。 块变量的声明语句从前至后分为了几部分:返回值类型,如int、double,如果未显式地声明块的返回值类型,可能会自动从块代码中推断返回类型(通过return语句)。块变量名用括号括住,块变量名前加^符号。参数类型用括号括住,多个参数以逗号分隔,如果参数列表为void,而且返回类型依靠推断,可以省略参数列表的void。等号,将后面的块赋值给前面的块变量(即myBlock)。以^开头并以;结束的块定义。块定义中又分为以下两个部分(除去开头的^和结尾的;外):参数列表,同函数的参数列表。块体,同函数体。值得注意的是,块可以使用同一作用域内定义的变量,而函数不行。一旦声明了块,你可以像使用函数一样调用它: int multiplier = 7; int (^myBlock)(int) = ^(int num) { return num multiplier; }; printf ( "%d", myBlock(3)); 2.行内块有时候,你不准备重复使用某个块,因此你不必为它想一个名称。那你可以使用行内块而不用声明为块变量。以下代码来自苹果文档:// gsort_b类似标准的 gsort_r 函数,但它最后一个参数是一个块。 char myCharacters[3] = { "TomJohn", "George", "Charles Condomine" }; qsort_b(myCharacters, 3, sizeof(char ), ^(const void l, const void r) { char left = (char )l; char right = (char )r; return strncmp(left, right, 1); }); // myCharacters 现在是 { "Charles Condomine", "George", TomJohn" } 在qsort_b 方法调用中,第4个参数就是一个匿名的块(行内块)。匿名块跟块变量不同,它没有变量名,因此你无法重用匿名块。下次调用这个块时,必须把整个块定义的代码再复制一遍。3.__block关键字块允许访问本地变量。这很重要。它使得我们在线程间共享变量变得简单,而且,你可以规定一个本地变量是否可以写,这可通过使用__block关键字,这是一种类类似register、auto和static存储类型修饰符。用__block修饰的变量,可以在所有同一作用域内的块,以及块复制之间共享数据。在指定作用域内的多个块能同时使用共享变量。如同块,__block变量也使用栈存储。如果使用block_copy拷贝块(或者向块发送copy消息),变量被拷贝到堆里。而且,__block变量的地址随后就会改变。__block变量有两个限制:不能是可变长度的数组,也不能是包含C99可变长度数组的结构体。下面显示了__block变量的使用: __block int x = 123; // x 是块可写的 void (^printXAndY)(int) = ^(int y) { x = x + y; printf("%d %d\n", x, y); }; printXAndY(456); // 打印出: 579 456 // x 现在的值是:579 下面显示了在块中使用多种类型的变量: extern NSInteger CounterGlobal; static NSInteger CounterStatic; { NSInteger localCounter = 42; __block char localCharacter; void (^aBlock)(void) = ^(void) { ++CounterGlobal; ++CounterStatic; CounterGlobal = localCounter; localCharacter = 'a'; }; ++localCounter; localCharacter = 'b'; aBlock(); }

优秀的个人博客,低调大师

《企业级ios应用开发实战》一3.6 可变参数

3.6 可变参数 我们知道,C和C++语言支持可变参数的函数,例如我们常用的NSLog和printf函数。Objective-C作为C语言的超集,当然毫无例外地也支持可变参数。迄今为止,我们至少用过了一种使用可变参数的方法,即NSString的stringWithFormat:方法。C语言通过stdarg.h库支持可变参数,Objective-C 也不例外。在C语言中,如果你要使用可变参数,必须包含头文件stdarg.h,但在Cocoa中却不必,因为苹果已经在 NSObjC Runtime.h中包含了stdarg.h。stdarg.h的定义如下: typedef __void va_list; #define va_start(ap, param) __builtin_va_start(ap, param) #define va_end(ap) __builtin_va_end(ap) #define va_arg(ap, type) __builtin_va_arg(ap, type) 首先定义了一个va_list类型,其实就是一个void,即可以指向任何类型的指针。你可以把它看成是char,因为char*实际上也可以指向任何内存单元的地址。然后是3个预定义宏,va_start、va_end和va_arg。可以看出stdarg.h完全是以“预定义宏”这种“古老”的方式来支持可变参数的。接下来我们看一个例子,该方法使用了一个可变参数,并将这些可变参数进行了累加,然后返回一个NSNumber: - (NSNumber ) addValues:(int) count, ... { va_list args; va_start(args, count); NSNumber value; double retval; for( int i = 0; i < count; i++ ) { value = va_arg(args, NSNumber ); retval += [value doubleValue]; } va_end(args); return [NSNumber numberWithDouble:retval]; } 代码说明:第1行是方法定义,该定义应当加到头文件中。省略号...表明方法接收一系列数目不定的参数,在...前面至少需要指定一个任意类型的参数。有时我们必须知道参数的个数以防止出现无效的引用,但在某种情况下,参数个数是可以通过其他参数推断出来的(例如NSLog或printf函数可以通过计算%号的个数推断可变参数的个数),或者对于NSMutableArray来说,它总是以nil终止。如果是最后一种方法,我们可以把方法重新定义为: - (NSNumber ) addValues:(NSNumber ) firstNumber, ... 这样,我们就可以用以下调用方式代替“addValues:3,num1,num2,num3”: addValues:num1,num2,num3; 这样,我们就可以省略第1个表示可变参数个数的int参数。第2行中的va_list是void *类型,因此它实际上是一个可变的对象数组。第3行用args来存放可变参数列表,而count则表示函数最后一个参数(即第一个“固定参数”)。这将使编译器把args指向第1个参数后的位置(通过count地址加上count变量的长度)。很奇怪吗?可变参数中第1个参数的位址为什么是“count地址+count的长度”?因为对于大多数C编译器,函数栈中参数的存放顺序是从右到左的,也就是说先放入可变参数的最后一个参数,再放可变参数的倒数第2个参数……,然后放可变参数的第1个参数,最后是固定参数count。而与此同时,栈的方向是向下的,即先入栈的数据位于高地址,后入栈的数据则位于栈的起始地址。这样,实际上最后放入的固定参数count的地址变成了栈的起始地址。而紧随count之后的地址则是可变参数的第1个参数地址,即“count地址+count的长度”,因此编译器要能找到第1个可变参数的地址,只要知道1个参数:count就够了,由count取得函数栈的起始地址,加上sizeof(count),得到第1个可变参数的地址。va_start的第1个参数args是一个输出参数,经过va_start调用之后,args将等于arg_start计算出来的第1个可变参数的地址。第6行是一个for循环,因为我们无法通过 args 自身推断 args 的大小,因此必须显式地用count来指定args的大小。或者可以使用nil终止的列表来检索可变参数。如果你使用nil终止的数组作为可变参数,则应该用下面一行来代替第6~7行: while( value = va_arg( args, NSNumber ) ) 第 7 行将 args 中的下一个参数放入 value,并显式地转为 NSNumber*(如果不知道类型,可以用id)。第10行表明,一旦使用完args列表,就关闭它 。提示:如果你使用va_arg(args,double)(或者float等其他原始类型),那么当你试图传递一系列整数作为参数时(例如:addValues:4,4,3,2,1),可能会出现一些古怪的结果。而如果你显式地将这些参数说明为double(例如,double num1,double num2,double num3,double num4)则不会有什么问题。这是因为,如果编译器看到一个方法有一个double参数但你却传递了一个整数给这个方法时,它会进行类型转换。但如果方法使用了可变参数,编译器无法知道参数所使用的类型,因此编译器只会简单地把参数作为整型处理。

优秀的个人博客,低调大师

《企业级ios应用开发实战》一3.7 本章小结

3.7 本章小结 Objective-C是C语言的扩展和超集。本章重点从C语言特性和面向对象特性两个方面对Objective-C的语言特性进行论述,包括基本语法(数据类型、常量/变量、分支与循环)、运行时特性(反射支持)和一些特有属性(NS类、类别和协议、消息、KVO和块)。通过这些介绍,我们对Objective-C的一些重要特性有了最基本的了解,从而为后续的学习打下坚实的基础。接下来,本书将陆续介绍iOS SDK中的一些重要框架,如UIKit、Core Animation、Quartz Core,以及其他一些第三方的开源框架。

优秀的个人博客,低调大师

《Android应用开发攻略》——2.6 在Android中创建闪屏

2.6 在Android中创建闪屏 Rachee Singh2.6.1 问题你打算创建应用程序加载时显示的闪屏(splash screen)。2.6.2 解决方案你可以采用活动或者对话框的形式构建闪屏。因为闪屏的目标在几秒钟之内就能完成,所以它可以在短时间或者单击闪屏上的一个按钮之后消失。2.6.3 讨论闪屏发明于PC时代,最初是在PC速度较慢的时候遮盖缓慢构建的GUI。供应商则将闪屏用于品牌宣传。但是在移动领域中,最长的应用程序启动时间可能少于1秒,人们开始认为闪屏已经不合时宜。在 eHealth Innovation中,我们对此进行了论证, BANT应用程序闪屏在1秒之后就消失。问题是:我们是否仍然需要闪屏?现在是否应该摒弃闪屏的概念?在大部分移动应用中,应用启动器中会显示名称和徽标,在其他许多屏幕中也会出现名称和徽标,是否应该

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册