Objective-C 和 Core Foundation 对象相互转换的内存管理总结
iOS允许Objective-C 和 Core Foundation 对象之间可以轻松的转换,拿 NSString 和 CFStringRef 来说,直接转换豪无压力:
CFStringRef aCFString = (CFStringRef)aNSString; NSString *aNSString = (NSString *)aCFString;
针对内存管理问题,ARC 可以帮忙管理 Objective-C 对象, 但是不支持 Core Foundation 对象的管理,所以转换后要注意一个问题:谁来释放使用后的对象。 本文重点总结一下类型转换后的内存管理。
倘若不使用ARC,手动管理内存,思路比较清晰,使用完,release转换后的对象即可。
//NSString 转 CFStringRef CFStringRef aCFString = (CFStringRef) [[NSString alloc] initWithFormat:@"%@", string]; //... CFRelease(aCFString); //CFStringRef 转 NSString CFStringRef aCFString = CFStringCreateWithCString(kCFAllocatorDefault, bytes, NSUTF8StringEncoding); NSString *aNSString = (NSString *)aCFString; //... [aNSString release];
- __bridge (不改变对象所有权)
__bridge_retained 或者 CFBridgingRetain() (解除 ARC 所有权)
__bridge_transfer 或者 CFBridgingRelease() (
给予 ARC 所有权)
- (void)viewDidLoad { [super viewDidLoad]; NSString *aNSString = [[NSString alloc]initWithFormat:@"test"]; CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString; (void)aCFString; //正确的做法应该执行CFRelease //CFRelease(aCFString); }
CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString; CFStringRef aCFString = (CFStringRef) CFBridgingRetain(aNSString);
- (void)viewDidLoad { [super viewDidLoad]; NSString *aNSString = [[NSString alloc]initWithFormat:@"test"]; CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString; aNSString = (__bridge_transfer NSString *)aCFString; }
CFBridgingRelease() 是__bridge_transfer的宏方法,下面两行代码等价:
aNSString = (__bridge_transfer NSString *)aCFString; aNSString = (NSString *)CFBridgingRelease(aCFString);
- (void)viewDidLoad { [super viewDidLoad]; NSString *aNSString = [[NSString alloc]initWithFormat:@"test"]; CFStringRef aCFString = (__bridge CFStringRef)aNSString; (void)aCFString; }
- (void)viewDidLoad { [super viewDidLoad]; CFStringRef aCFString = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII); NSString *aNSString = (__bridge NSString *)aCFString; (void)aNSString; CFRelease(aCFString); }
欢迎来到PhoneGap!既然选择阅读《PhoneGap入门经典》,那就说明你已经听说过PhoneGap,并且想学习更多有关如何使用它来开发跨平台移动应用程序的知识。《PhoneGap入门经典》深入研究了PhoneGap API的不同部分,并介绍如何使用PhoneGap工具来建立不同的应用程序。现在是向PhoneGap深度进军的时候了。在转入对API规范的了解之前,研究一下使用主要的组件可以创建的内容的例子还是有用的——这可以使你的有关应用程序的创意源源不断。
PhoneGap的作用先前,已经看到了一些PhoneGap应用程序的快速展示。现在让我们简单介绍一下可能会用到的一些API的主要组件。
1. 使用通讯录通讯录列表是一个在所有智能手机上都相当普遍的功能。利用PhoneGap,可以便捷地操作以下通讯录功能:
● 使用create()方法创建联系人
● 使用save()方法保存联系人
● 使用find()方法查找联系人
● 使用clone()方法复制联系人
使用remove()方法删除联系人
要创建联系人,可以给contacts.create()传递一个JavaScript Object Notation(JSON)对象,这样就只在应用程序内存中创建联系人。要将新的联系人保存到Contacts数据库,应该使用save()方法。
PhoneGap API支持联系人的不同属性字段(如显示的姓名、昵称、电话号码、电子邮件、地址、生日、性别、照片、时区等)。这些大多数都可以通过运行contacts.find()来获取匹配用户的列表。
clone()方法允许快速复制内存中的一个通讯录,并随即对不同的属性进行修改。例如,也许有一组具有相同实际地址的联系人。克隆原始通讯录可以非常迅速地完成属性列表的改变。
顾名思义,remove()方法可用于从设备的通讯录数据库中删除联系人。
通过这一方法和功能的基本列表,可以容易地将不同视图合并在一起,来使用户实现通讯录的搜索、创建新的联系人、对现有的联系人进行修改或者删除联系人。例如,你的应用程序也许可以帮助用户对他们的所有联系人基于搜索条件(诸如邮政编码或存在的电话号码)进行批处理操作。
2. 使用摄像头大多数智能手机都内置了摄像头。PhoneGap API提供了两种捕获图像的方法。一种是通过camera对象来访问摄像头,另一种是使用Media Capture API(本章稍后就会学到)。特别是,camera.getPicture()方法根据传递给它的数据源类型(CAMERA或PHOTOLIBRARY)来确定是使用摄像头来照相,还是从设备的相册里检索照片。
还可以选择让摄像头提供基于Base64编码的图像(这是默认设置)或者图像文件的位置。一旦有了这一信息,就可以用它来渲染一幅图像、向远程服务器提交数据或者在本地存储数据。
警告:然而需要留意的是,由于最新最强大的智能手机使用了一些具有高分辨率图形的超高品质的摄像头,如果选择使用基于Base64编码的数据,那么会碰到内存管理方面的问题。
一个有趣的选项是捕获一幅可编辑的照片。在照片被设备捕获后,它会提供有关诸如图像裁剪方面的各种可能的操作。
注意:Android手机会忽略allowEdit参数。
用Camera API可以建立哪些应用程序?一个好的例子可能就是一个照片分享的应用程序,它允许获取一张图片,进行一些基本的编辑,然后将其发布到一台远程Web服务器上去。
注意:那些熟悉社会摄影应用程序的人将会注意到,这实际上指的是一款所谓的图片分享应用程序——Instagram。
其他可能的应用包括记录工具,它可以在照过相后在图像上再添加一些注释。或者,甚至可以有这样的应用,让营业员对他们在商店里所找到的商品拍照,并将其添加到收藏夹,以便和其他朋友分享。
3. 使用地理定位另一个现代智能手机的特征就是它们的地理定位能力。大多数智能手机可以使用GPS或其他技术,以一定的精度来告知当前所处位置的经纬度。当然,如果设备是使用蜂窝电话基站来进行三角定位,那位置会一点都不精确。并且,如果网络连接不可用,那就完全失效了。
PhoneGap的Geolocation API可以获取当前位置(经度和纬度,但也会包括像海拔高度这样的其他一些细节)并会监视一个位置以防变化。如果想追踪设备的移动,这个功能就非常有用。
在应用程序中有许多不同的方法来达到地理定位的目的。可以使用地理定位数据来丰富其他数据—— 例如,可以在应用程序所摄取的任意照片上添加经纬度信息。或者,在用户创建的任何注释上添加地理定位数据。抑或通过将地理定位信息发送到远程Web服务器,可以使调度员掌握现场工作人员的位置情况。
4. 使用媒体文件在PhoneGap中,Media Capture API作为一个好的方法,并不只是用于捕获照片。同样还可以用它来捕获音频和视频数据。正如所预期的那样,Media Capture API允许开始和停止记录、播放、暂停以及停止媒体文件,甚至可以显示一个音频文件的持续时间。
从应用程序的角度来看,可以使用Media Capture API来创建不同的声音和视频记录应用程序——想想拥有一个能够记录音频和视频,并在一个包上添加注释或照片的工具该是多么有用啊(对于那些使用Evernote的人来说,将会意识到这样描述是恰如其分的)。还可以建立一个应用程序来对不同的音频文件进行采样。如果建立了一个移动应用程序来展示音乐或讲话记录的目录,这就将非常有用了—— PhoneGap将播放本地存储的文件,对于在远程Web服务器上的也一样。
5. 使用存储选项那些已经使用了HTML5的存储选项的人将会高兴地得知PhoneGap也支持Web SQL数据库。和HTML5一样,将可以本地使用SQLite,这通常足以创建出各种丰富的数据后端。
例如,可以建立一个允许用户在设备和远程Web数据库之间同步数据的应用程序。应用程序可以使用一个简单的Ajax调用从一个远程数据库请求特定数据,使用JSON将数据传送到手机,然后对JSON对象进行转换并存储到SQLite中。这样,任何由用户在本地进行的修改都可以重新传递到远程数据库中。
应用的可能性是广泛的—— 例如具有移动应用功能的以公司内部网为基础的知识库,让用户下拉信息,进行必要的修改并发布回内部网上。或者,仅仅是用更丰富的数据增强设备特定的应用程序—— 例如,前面提到的可以让用户照相和记录音频的笔记应用程序,能够使用SQLite为每一张所照的照片存储注释和元数据。
API概览由于本书通篇都致力于描述使用PhoneGap API来工作,因此没有必要对API中的内容细节花费大量笔墨。然而,大致了解一下PhoneGap API中当前可用的内容还是有好处的。以下是按字母顺序列出的API组件:
● Accelerometer—— 接入设备的运动传感器
● Camera—— 使用设备的摄像头进行拍照
● Capture—— 使用设备的媒体捕获应用程序捕获媒体文件
● Compass—— 获取设备的朝向
● Connection—— 快速检查网络状态(无论是WiFi还是蜂窝网络)
● Contacts—— 使用设备的联系人数据库
● Device—— 收集设备特定的信息
● Events—— 通过JavaScript连接本地事件
● File—— 通过JavaScript连接本地文件系统
● Geolocation—— 使得应用程序能够感知地理位置
● Media—— 记录并回放音频文件
● Network—— 快速检查网络状态
● Notification—— 可视、可听和可触的设备通知
● Storage—— 连接设备的本地存储选项
在以后的几个章节中,将学习到安装PhoneGap的方法,随后首先了解的是Events API,它将奠定如何启动任意应用程序的基础(换句话说,如果没能检测到代表设备准备好的deviceready,那么就做不了什么)。之后还将进行网络状态的检查、获取设备信息,并关闭自定义的通知。一旦掌握了这些基础,就可以开始真正进入到API的世界。
移动设计问题到目前为止,已经笼统地学习了有关PhoneGap API的很多知识,接下来还将通过本书其余章节学习更多的有关内容。
然而,要特别强调的一件事是:PhoneGap应用程序不仅仅是关于PhoneGap API。要成功建立一个HTML5移动应用程序,不但要理解HTML的基础,还要掌握CSS和JavaScript。此外,如果打算使用其他框架(如非常流行的jQuery),就必须对其工作原理有牢固的理解。
特别地,在设备上要建立一个动态Web应用程序,而不是静态HTML页面或系列页面——简单地将整个网站移植到PhoneGap并展示给用户是不明智的。
换句话说,必须考虑设备可视屏幕的大小。例如,只是在iPhone的320×480像素的屏幕上倾倒一堆滚动文字和巨大的设计元素(如背景图像),是没有什么好处的。
一个更好的办法是重新分割任意的内容,或者提供一个更精简版本的用户界面(UI)元素(特别是导航)。本书并非有关移动设备用户体验的书籍,也不打算在小屏幕上的布局或可用性方面提供任何建议。当然,要留意用户将会注意并对必须滚屏或用手指缩放获得所需信息感到不满。
一个好的方法是使用HTML元素为内容(对于初学者来说,特别是标题、列表和按钮)引入语义结构,而且可以方便地使用CSS进行样式化。
另外需要考虑的是,移动设备具有和运行在桌面或笔记本设备上的普通Web浏览器不同的时延和初始化特性。也就是说,当用户加载PhoneGap应用程序时,应用程序必须经过一系列初始化过程才能使用。大型、杂乱或极度令人费解的布局将会使运行和解析都变得更慢。
鉴于此,出现了很多不同的框架来简化应用程序,如xuijs(如图1所示)、jQTouch(如图2所示)以及jQuery Mobile(如图3所示)。
图1 xuijs框架
图2 jQTouch框架
图3 jQuery Mobile框架
不同的设备对不同框架的响应也不相同(例如,jQTouch上的动画在特定Android设备上似乎极不友好,以及xuijs看起来是唯一能在老版本的BlackBerry设备上运行的框架)。但不要被这些吓到,毕竟使用框架来创建一个可用的用户界面常常要比你自己进行集成,然后在不同设备上进行测试迅速得多。
最后同样重要的是,在一些手机上,从一个页面链接到另一个页面也许会造成内存问题或交互缓慢。最好的一种实践方法是尽量在一个页面上保留最多的功能,然后使用JavaScript函数将信息动态加载到页面上。可以使用document.getElementById()或者使用jQuery的$()符号。如果使用了一个框架,则有大量的这种操作可以为你所用——例如,在jQTouch中,单击一个链接就实际请求加载一个特定的文档对象模型(DOM)元素,而不是打开一个单独的页面。
《PhoneGap入门经典》试读电子书免费提供,有需要的留下邮箱。
3楼waylife昨天 16:44html5有点超前,至少目前来说,成熟期太概在2-3年内2楼lihe777999昨天 13:20我看不懂1楼hilter1949昨天 14:28打算今年学习html5 ,正好有个方向。这是我的邮箱:hitler1949@163.com常用的一些效果:
文字跑马灯
同样的,先上效果图,
实现起来非常简单,TextView中已经提供了多种显示接口,可以在文字显示不下时,以各种方式进行显示
例如
前置省略号
后置省略号
跑马灯显示
主要的区别在Xml中android:ellipsize 属性的不同
android:ellipsize
设置当文字过长时,该控件该如何显示。有如下值设置:”start”—–省略号显示在开头;”end”——省略号显示在结尾;”middle”—-省略号显示在中间;”marquee” ——以跑马灯的方式显示(动画横向移动)
由此只需要在Xml文件中设置TextView的ellipsize属性为marquee即可
属性详解:
Android:autoLink
设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接。可选值(none/web/email/phone/map/all)android:autoText
如果设置,将自动执行输入值的拼写纠正。此处无效果,在显示输入法并输入的时候起作用。
android:bufferType
指定getText()方式取得的文本类别。选项editable 类似于StringBuilder可追加字符,也就是说getText后可调用append方法设置文本内容。spannable 则可在给定的字符区域使用样式,参见这里1、这里2。
android:capitalize
设置英文字母大写类型。此处无效果,需要弹出输入法才能看得到,参见EditView此属性说明。
android:cursorVisible
设定光标为显示/隐藏,默认显示。
android:digits
设置允许输入哪些字符。如“1234567890.+-*/% ()”
android:drawableBottom
在text的下方输出一个drawable,如图片。如果指定一个颜色的话会把text的背景设为该颜色,并且同时和background使用时覆盖后者。
android:drawableLeft
在text的左边输出一个drawable,如图片。
android:drawablePadding
设置text与drawable(图片)的间隔,与drawableLeft、 drawableRight、drawableTop、drawableBottom一起使用,可设置为负数,单独使用没有效果。
android:drawableRight
在text的右边输出一个drawable。
android:drawableTop
在text的正上方输出一个drawable。
android:editable
设置是否可编辑。
android:editorExtras设置文本的额外的输入数据。
android:ellipsize
设置当文字过长时,该控件该如何显示。有如下值设置:”start”—-省略号显示在开头;”end” ——省略号显示在结尾;”middle”—-省略号显示在中间;”marquee” ——以跑马灯的方式显示(动画横向移动)
android:freezesText设置保存文本的内容以及光标的位置。
android:gravity设置文本位置,如设置成“center”,文本将居中显示。
android:hintText
为空时显示的文字提示信息,可通过textColorHint设置提示信息的颜色。此属性在 EditView中使用,但是这里也可以用。
android:imeOptions
附加功能,设置右下角IME动作与编辑框相关的动作,如actionDone右下角将显示一个“完成”,而不设置默认是一个回车符号。这个在EditView中再详细说明,此处无用。
android:imeActionId设置IME动作ID。
android:imeActionLabel设置IME动作标签。
android:includeFontPadding设置文本是否包含顶部和底部额外空白,默认为true。
android:inputMethod
为文本指定输入法,需要完全限定名(完整的包名)。例如:com.google.android.inputmethod.pinyin,但是这里报错找不到。
android:inputType设置文本的类型,用于帮助输入法显示合适的键盘类型。在EditView中再详细说明,这里无效果。
android:linksClickable设置链接是否点击连接,即使设置了autoLink。
android:marqueeRepeatLimit
在ellipsize指定marquee的情况下,设置重复滚动的次数,当设置为 marquee_forever时表示无限次。
android:ems设置TextView的宽度为N个字符的宽度。这里测试为一个汉字字符宽度
android:maxEms设置TextView的宽度为最长为N个字符的宽度。与ems同时使用时覆盖ems选项。
android:minEms设置TextView的宽度为最短为N个字符的宽度。与ems同时使用时覆盖ems选项。
android:maxLength限制显示的文本长度,超出部分不显示。
android:lines设置文本的行数,设置两行就显示两行,即使第二行没有数据。
android:maxLines设置文本的最大显示行数,与width或者layout_width结合使用,超出部分自动换行,超出行数将不显示。
android:minLines设置文本的最小行数,与lines类似。
android:lineSpacingExtra设置行间距。
android:lineSpacingMultiplier设置行间距的倍数。如”1.2”
android:numeric
如果被设置,该TextView有一个数字输入法。此处无用,设置后唯一效果是TextView有点击效果,此属性在EdtiView将详细说明。
android:password以小点”.”显示文本
android:phoneNumber设置为电话号码的输入方式。
android:privateImeOptions设置输入法选项,此处无用,在EditText将进一步讨论。
android:scrollHorizontally设置文本超出TextView的宽度的情况下,是否出现横拉条。
android:selectAllOnFocus如果文本是可选择的,让他获取焦点而不是将光标移动为文本的开始位置或者末尾位置。 TextView中设置后无效果。
android:shadowColor指定文本阴影的颜色,需要与shadowRadius一起使用。
android:shadowDx设置阴影横向坐标开始位置。
android:shadowDy设置阴影纵向坐标开始位置。
android:shadowRadius设置阴影的半径。设置为0.1就变成字体的颜色了,一般设置为3.0的效果比较好。
android:singleLine
设置单行显示。如果和layout_width一起使用,当文本不能全部显示时,后面用“…”来表示。如android:text="test_ singleLine "
android:singleLine="true" android:layout_width="20dp"将只显示“t…”。如果不设置singleLine或者设置为false,文本将自动换行
android:text设置显示文本.
android:textAppearance
设置文字外观。如 “?android:attr/textAppearanceLargeInverse”这里引用的是系统自带的一个外观,?表示系统是否有这种外观,否则使用默认的外观。可设置的值如下:textAppearanceButton/textAppearanceInverse/textAppearanceLarge/textAppearanceLargeInverse/textAppearanceMedium/textAppearanceMediumInverse/textAppearanceSmall/textAppearanceSmallInverse
android:textColor
设置文本颜色
android:textColorHighlight
被选中文字的底色,默认为蓝色
android:textColorHint设置提示信息文字的颜色,默认为灰色。与hint一起使用。
android:textColorLink文字链接的颜色.
android:textScaleX设置文字之间间隔,默认为1.0f。
android:textSize设置文字大小,推荐度量单位”sp”,如”15sp”
android:textStyle设置字形[bold(粗体) 0, italic(斜体) 1, bolditalic(又粗又斜) 2] 可以设置一个或多个,用“|”隔开
android:typeface设置文本字体,必须是以下常量值之一:normal 0, sans 1, serif 2, monospace(等宽字体) 3]
android:height设置文本区域的高度,支持度量单位:px(像素)/dp/sp/in/mm(毫米)
android:maxHeight设置文本区域的最大高度
android:minHeight设置文本区域的最小高度
android:width设置文本区域的宽度,支持度量单位:px(像素)/dp/sp/in/mm(毫米),与layout_width 的区别看这里。
android:maxWidth设置文本区域的最大宽度
android:minWidth设置文本区域的最小宽度