说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

盘点一些iOS开发技巧:Swift和Objective-C

HTML文档下载 WORD文档下载 PDF文档下载
对苹果开发者来讲,2014年是令人难以置信的一年。在这短短的一年中发生了如此多的变化:在充满吸引力的Swift面前,我们几乎忘了之前是如何痴迷OC;以及充满想象力的iOS8和WatchKit,难以想象还有什么API能与之相比。

回顾过去一年发生在我们身边的事情时,有一点不得不提:对苹果开发者来讲,2014年是令人难以置信的一年。在这短短的一年中(有关APP的开发)发生了如此多的变化:在充满吸引力的Swift面前,我们几乎忘了之前是如何痴迷于Objective-C;以及充满想象力的iOS 8和WatchKit,难以想象还有什么API能与之相比。


NSHipster的惯例:请可爱的童鞋们,在新年的第一天,为大家展示你们(在开发中)常使用的技巧和方法。如今,随着来自Cupertino(苹果总部,位于旧金山)和众多开源社区的一系列API的涌现,妈妈再也不用担心我们找不到有趣的东西来分享啦!

在此,感谢以下童鞋们所做的贡献:

Colin Rofls、Cédric Luthi、Florent Pillet、Heath Borders、Joe Zobkiw、Jon Friskics、Justin Miller、Marcin Matczuk、Mikael Konradsson、Nolan O'Brien、Robert Widmann、Sachin Palewar、Samuel Defago、Sebastian Wittenkamp、Vadim Shpakovski、Zak。

成员函数的使用技巧(来自Robert Widmann)

在用静态方式调用Swift类和结构中的成员函数时,通常使用以下格式:

Object->(参数)->Things

比如,你可以用以下两种方式调用reverse():

[1,2,3,4].reverse( )Array.reverse([1,2,3,4])

用@()来封装C字符串(来自Samuel Defago)

事实上文字大部分时候是数字和字母的集合,使用C字符串,尤其当我在使用运行时编码的时候,我常常会忘记用UTF8编码、以NULL结束:Objective-C字符串封装:

NSString *propertyAttributesString =    @(property_getAttributes(class_getProperty([NSObject class], "description")));// T@"NSString",R,C

AmIBeingDebugged

Nolan O'Brien在这篇Q&A技术文档中让我们注意到了AmIBeingDebugged函数方法:

#include <assert.h>#include <stdbool.h>#include <sys/types.h>#include <unistd.h>#include <sys/sysctl.h>static Bool AmIBeingDebugged(void) {    int mib[4];    struct kinfo_proc info;    size_t size = sizeof(info);    info.kp_proc.p_flag = 0;    mib[0] = CTL_KERN;    mib[1] = KERN_PROC;    mib[2] = KERN_PROC_PID;    mib[3] = getpid();    sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);    return (info.kp_proc.p_flag & P_TRACED) != 0;}

使用延迟存储属性(来自Colin Rofls)

在开发过程中,应该避免使用Optionals类型,更不应该使用隐式解包optionals类型。你想声明一个var变量却不想给一个初始值?使用“lazy”吧,唯一要注意的就是:在你的属性被赋值之前不要调用getter方法即可(童叟无欺!)

lazy var someModelStructure = ExpensiveClass()

假如你仅仅对这var变量调用set方法,而没有调用getter方法的话,这个被lazy修饰的var变量不会被赋值。例如,用lazy修饰那些直到viewDidLoad时才需要初始化的views变量就会非常合适。

获取Storyboard视图容器里的子视图控制器(来自Vadim Shpakovski)

有一个比较方便的方法来获取故事板视图容器里的子视图控制器:

// 1. A property has the same name as a segue identifier in XIB@property (nonatomic) ChildViewController1 *childController1;@property (nonatomic) ChildViewController2 *childController2;// #pragma mark - UIViewController- (void)prepareForSegue:(UIStoryboardSegue *)segue                 sender:(id)sender{    [super prepareForSegue:segue sender:sender];     // 2. All known destination controllers assigned to properties    if ([self respondsToSelector:NSSelectorFromString(segue.identifier)]) {        [self setValue:segue.destinationViewController forKey:segue.identifier];    }}- (void)viewDidLoad {    [super viewDidLoad];    // 3. Controllers already available bc viewDidLoad is called after prepareForSegue    self.childController1.view.backgroundColor = [UIColor redColor];    self.childController2.view.backgroundColor = [UIColor blueColor];}

重复运行项目,不重复构建项目(来自Heath Borders)

假如你一直在不停地调试同一个问题,你可以在不重复构建的情况下运行你的APP,这样:“Product>Perform Action>Run without Building” 

快速获取Playground资源(来自Jon Friskics)

Swift里的所有Playground共享相同的数据目录:/Users/HOME/Documents/Shared Playground Data

如果你喜欢使用很多Playgrounds,你将需要在上述共享目录下为每个Playground新建对应的子目录,来存储每个Playground用到的数据;但是那之后你需要告诉每个Playground在哪儿可以获取其对应的数据。下面是我常用的一个辅助解决方法:

func pathToFileInSharedSubfolder(file: String) -> String {    return XCPSharedDataDirectoryPath + "/" + NSProcessInfo.processInfo().processName + "/" + file}

processName属性是Playground文件的名字,因此只要你已经在Playground数据共享文件目录下以相同的名字新建了一个子目录,那么你可以很容易访问这些数据,和读取本地JSON数据一样:

var jsonReadError:NSError?let jsonData = NSFileManager.defaultManager().contentsAtPath(pathToFileInSharedSubfolder("data.json"))!let jsonArray = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &jsonReadError) as [AnyObject]

....或者访问本地图片

let imageView = UIImageView()imageView.image = UIImage(contentsOfFile: pathToFileInSharedSubfolder("image.png"))

Please attention!本篇文章剩余的部分来自Cédric Luthi大神的贡献,他分享了一些比较有用的开发技巧和技术,这些内容足够自成一篇,值得细细品读。这里再次感谢Cédric!

CocoaPods大揭秘

这儿有一个快速的方法来检查APP里用到的所有pods:

$ class-dump -C Pods_ /Applications/Squire.app | grep -o "Pods_\w+"

CREATE_INFOPLIST_SECTION_IN_BINARY

注意Xcode中为命令模式APP(command-line apps)设置的CREATE_INFOLIST_SECTION_IN_BINARY属性。这比使用-sectcreate__TEXT__info_plist链接标志位更加容易,前者还把已经编译好的Info.plist文件嵌入在二进制编码中。

关于如何向苹果提需求,它也给我们上了一课,这个特性需求早在2006年的 rdar://4722772 被提出,但直到7年后才被满足。

(译者注:言外之意是它是反面教材,应该更有技巧的提需求)

禁用dylib钩子(来自Sam Marshall)

Sam Marshall这个技巧可谓是走自己的路,让黑客无路可走。

在你的“Other Linker Flags”里加上下面这行:

-Wl,-sectcreate,__RESTRICT,__restrict,/dev/null

NSBundle -preferredLocalizations

某些时候,你需要知道APP当前使用的是什么语言。通常,大家会使用NSLocal+preferredLanguages. 可惜的是这个方法不会告诉你APP实际呈现的文字语种。你仅仅会得到iOS系统里“Settings->General->Language&Region->Preferred Language”列表中的选项,或者OSX系统里“System Preferences->Language & Region->Preferred Languages”列表中的选项。想象一下:优先语言列表中只有{英语,法语},但你的APP仅使用德语;调用[[NSLocal preferredLanguages] firstObject]返回给你的是英语,而不是德语。

正确的方法是用[[NSBundle mainBundle] preferredLocalizations]方法。

苹果的开发文档是这样说的:

一个包含了在bundle中本地化的语言ID的NSString对象的数组,里面的字符串排序是根据用户的语言偏好设置和可使用的地理位置而来的。

NSBundle.h里的备注:

一个bundle中本地化的子集,重新排序到当前执行坏境的优先序列里,main bundle的语言顺序中最前面的是用户希望在UI界面上看到的语种。

当然你也许需要调用这个方法:

NSLocal+canonicalLanguageIdentifierFromString:

来确保你使用的文字语种是规范的语种。

保护SDK头文件

如果你用dmg安装Xcode,那么看看这篇Joar Wingfors的文章,它讲述了如何通过保留所有权来避免SDK头文件被意外修改:

$ sudo ditto /Volumes/Xcode/Xcode.app /Applications/Xcode.app

任意类型的实例变量检测

为了达到逆向处理的目的,查询对象的实例变量是一个常见可靠的途径。通常调用对象valueForKey:方法就能达到这一目的,除了少数重写了类方法+accessInstanceVariablesDirectly的类屏蔽了该操作。

下面是一个例子:当实例变量有一个为任意类型的属性时,上述提到的操作无效

这是iOS6.1 SDK中MediaPlayer 框架的一段引用:

@interface MPMoviePlayerController : NSObject {    void *_internal;    // 4 = 0x4    BOOL _readyForDisplay;  // 8 = 0x8}

因为 id internal=[moviePlayerController valueForKey:@”internal”] 无效,下面有一个笨办法来取得这个变量:

id internal = *((const id*)(void*)((uintptr_t)moviePlayerController + sizeof(Class)));

注意!不要随意调用这段代码,因为ivar的布局可能改变(指针偏移量计算可能出错)。仅在逆向工程中使用!

NSDateFormatter +dateFormatFromTemplate:options:locale:

友情提示:假如你调用[NSDateFormatter setDateFormat],而没有调用[NSDateFormatter dateFormatFromTemplate:options:local:],n那么很可能出错。

苹果文档:

+ (NSString *)dateFormatFromTemplate:(NSString *)template                             options:(NSUInteger)opts                              locale:(NSLocale *)locale

不同地区有不同的日期格式。使用这个方法的目的:得到指定地区指定日期字段的一个合适的格式(通常你可以通过currentLocal查看当前所属地区)

下面这个例子给我们表现了英式英语和美式英语不同的日期格式:

NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];NSLocale *gbLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"]; NSString *dateFormat;NSString *dateComponents = @"yMMMMd"; dateFormat = [NSDateFormatter dateFormatFromTemplate:dateComponents options:0 locale:usLocale];NSLog(@"Date format for %@: %@",    [usLocale displayNameForKey:NSLocaleIdentifier value:[usLocale localeIdentifier]], dateFormat); dateFormat = [NSDateFormatter dateFormatFromTemplate:dateComponents options:0 locale:gbLocale];NSLog(@"Date format for %@: %@",    [gbLocale displayNameForKey:NSLocaleIdentifier value:[gbLocale localeIdentifier]], dateFormat); // Output:// Date format for English (United States): MMMM d, y// Date format for English (United Kingdom): d MMMM y

通过调试获取内部常量

近期,Matthias Tretter在Twitter上问到:

有人知道在iOS8里modal viewController presentation的默认动画时间和跳转方式吗?

我们在UIKit的类库中发现了这样一个函数:[UITransitionView defaultDurationForTransition:],并在这个方法的位置加一个断点:

(lldb) br set -n "+[UITransitionView defaultDurationForTransition:]"
模态显示一个viewController,就会停在这个断点,输入finish执行该方法:

(lldb)finish
在defaultDurationForTransition:被执行时,你就能读到结果(在xmm0寄存器里)

(lldb) register read xmm0 --format float64    xmm0 = {0.4 0}
回复:默认动画时间0.4s

DIY 弱关联对象

不幸的是,关联对象OBJC_ASSOCIATION_ASSIGN策略不支持引用计数为0的弱引用。幸运的是,你可以很容易实现它,你仅仅需要一个简单的类,并在这个类里弱引用一个对象:

@interface WeakObjectContainter : NSObject@property (nonatomic, readonly, weak) id object;@end@implementation WeakObjectContainter- (instancetype)initWithObject:(id)object {    self = [super init];    if (!self) {        return nil;    }    self.object = object;    return self;}@end
然后,通过OBJC_ASSOCIATION_RETAIN(_NONATOMIC)关联WeakObjectContainter:

objc_setAssociatedObject(self, &MyKey, [[WeakObjectContainter alloc] initWithObject:object], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
用object属性指向这个所需的引用计数为0的弱引用对象。

id object = [objc_getAssociatedObject(self, &MyKey) object];

英文文章来源:NSHipster,译文出自:CocoaChina

(责编/刘璐璐)

$.getScript(url, callback)-JQuery API $.post(url, params, callback)-JQuery API ajaxComplete(callback)-JQuery API ajaxError(callback)-JQuery API ajaxSend(callback)-JQuery API ajaxStart(callback)-JQuery API ajaxStop(callback)-JQuery API ajaxSuccess(callback)-JQuery API load(url, params, callback)-JQuery API loadIfModified(url, params, callback)-JQuery API serialize()-JQuery API Accordion(settings)-JQuery API activate(index)-JQuery API button(hash)-JQuery API center()-JQuery API $.cookie(name)-JQuery API $.cookie(name, value, options)-JQuery API height()-JQuery API innerHeight()-JQuery API innerWidth()-JQuery API offset()-JQuery API outerHeight()-JQuery API outerWidth()-JQuery API scrollLeft()-JQuery API scrollTop()-JQuery API width()-JQuery API ajaxForm(object)-JQuery API ajaxSubmit(object)-JQuery API clearForm()-JQuery API clearInputs()-JQuery API fieldSerialize(true)-JQuery API 如何让打开的窗口总在上面?谢谢 黑屏,我以束手无策了 selection.find.execute如何得知整篇文档已经找完了? 每次csdn开久了,系统便特别的慢,和论坛的设计有关吗? 怎样得到一个自动递增的标示列的下一次取的值? marco里面执行命令时能不能添加参数? 怎样用 VB 将数据写入文本文件?怎样更新文本文件中的数据? 想请问一个关于数据传输的问题,如何来实现呢 动态数组问题?? FLASH转成GIF动画 在win2k下出现内存不能为read,,是什么问题??? 403 Forbidden? 有谁知道比较好的HTML的入门的书吗?请告诉我!!! 我有一个关于JSP中文显示问题? 求助,查询lookup,locate,关于variant 谁用过Raize 3.06控件组?请教RzImageComboBox控件怎么用? 在程序中如何打开系统的notepad或wordpad并同时显示字符串? 今天学了一个下午的五笔,进步不小,放分。 asp.net中有自己带的treeview类吗? 谁知道学习汇编语言的网站 !!help! 今天刚装了adsl,可是在win98下用不了,连通信公司的人都没辙(100分) api中怎么知道哪个函数用在哪个dll rave 的最版在哪里可找到 rave 的最版在哪里可找到 !!help! 今天刚装了adsl,可是在win98下用不了,连通信公司的人都没辙(100分) 救救我啊,关系着我的生计呀! 在Window2000上安装Redhat7.3后,机器速度慢得难以让人忍受 delphi5中数据集问题 !!help! 今天刚装了adsl,可是在win98下用不了,连通信公司的人都没辙(100分) 在线:请推荐几本OpenGL的好书!!! VI高级技巧征集中,欢迎大家来交流,谢绝灌水! WINDOWS 2003 SERVER 安装问题 存储过程可以返回记录集吗? CListBox的问题 请问!那位哥哥姐姐可以教我学习呢!? 页眉页角问题 一个关于package的初级问题 窗口大小 win2k+诺顿杀毒软件企业版~~~~~~~~~~~等待,立即送分! 请问我如何将CStatic透明化,即上面显示的字能够映在窗体上,并不是映在灰色CStatic控件上。???????????????? 网页发送短信是如何实现的? 陷入死循环啦!!! 紧急求助!!!!![2000密码] 为什么只能添加一条记录?帮帮忙,谢谢 谁知道比较好的学习汇编语言的网站 如何用JS打开一个文件对话框 有什么办法能让fsck的时候,不需要手动确认? 如何将编写好的*.chm文件连接到编写的应用程序中?(急) 高手请进!SQL SERVER出现问题! 急!!!请教计算机网络中的停止等待协议算法 哪能找到一个图书管理系统示例的源代码,谢谢 He took de wood from trees and made-----into paperA thoseB thatC themD it 园林施工的暂定金到底是什么意思 直译they recognize a bargain when they see it 圆O的半径为定长r A是圆O外一个定点 P是圆上任意一点 线段AP的垂直平分线L和直线OP交于点Q当点P在圆上运动求点Q的轨迹 (如图) 提交问题英文怎么翻译? 英文Made of 90% post-consumer recycled plastic是什么意思 在三角形ABC内,sinA:sinB:sinC=5:11:13,则三角形是什么三角形 look at ---- skiet.I boudht it for Mother on Mother's day ,isn't it nice?oh ,what--- nice presen 不同文化形态对园林产生与发展的影响. 帮我看看这个说法是否正确“一国货币汇率下跌即货币对外贬值,通常会引起出口扩大和进口减少,国内物价上涨,国际储备增加,就业增加和国民收入增长,资金外逃.”这个说法是否正确,请各位 How can you leave the room with two legs and return with six legs? make the arms ahd legs move up and down 枪能射中目标由于准星和XX对齐.请问XX是什么呢?本身是到几何题的.理由是什么两点确定一条直线. DIVING WITH MY CAR 歌词 我想在知道上提问题,翻译一句英文.总是提交不上,操作失败请重试.求原因 W_______ can be made into flour.填什么? I run with my legs怎么读 长螺线管求磁通量一个密绕的细长螺线管,每厘米长度绕有10匝细导线,螺线管的横截面积为10平方厘米,当螺线管中通入10A的电流时,它的横截面上的磁通量为多少? Bamboo can ___ paper.A used to make B be used make C be used to make D be used to making 这个说法正确吗在氧化还原反应中氧化剂一定得到电子还原剂一定失去电子请详细说出理由 来的磁场方向为标准,还是以变化后的磁场方向为标准? 为什么①这个说法是对的? How can you leave the room whth two legs and return with six legs?请问这道英语智力题的中文释义和答案是什么? 谷歌上面的翻译怎么用?我下工具包以后点翻译为什么没反应呢?谢谢了 十万火急.带式输送机的驱动装置1 ,输送带的速度V(m/s) 1.82 ,输送带有效拉力F (N) 14003 ,滚筒直径 D (mm) 3504 ,输送带速允许偏差 5% 左右5 ,运送物料 沙子6 ,每天工作班数 2注:采用斜齿轮传动 her arms are long的同义句 乔斯坦·贾德的《苏菲的世界》上架哪一类? 带式输送机驱动装置有哪些种类?各有何种特性? 忆秦娥·娄山关这首词的词牌是( )他跟词的( )有关:词题是(),他跟词的()有关.. “你怎么可以这么做?”翻译英文,用could what can the white water be made into?的意思 字典中笔画最多哪个字.差不多也行 如何自我改变,来改变磁场?我呢,是一个常被欺负的人,以前会因此牵动情绪,近年来,则学会隐藏受伤.比如说,大家一起逛街,挑下手的小东西,我对老板出价,说两个100元,老板一言不发,从我手上把 making a model car 同义句 our arms are long 英语翻译如题 can you making a model car哪错了,应该改为什么 我要找一种粘性材料我需要这么一种材料,他有固定的外形,质地柔软,能稳固地粘合上人体的皮肤且能负担一定的重量和震动,对皮肤无害而且不会感觉到不适,能反复使用.不知有没有符合我要 根据句意及首字母填空 1.I have no[m ]with me,I can't buy it 2.The coat is too[e ]for me to buy3.We can[l ]from each other4.I'm from the PRC,I'm[C ]5.It's hot now,Let's[s ]in the lake6.The panda is very shy,so please be very[q ]7.Mary is good “翻几倍”这个说法正确吗?有些人经常说“营业额翻了3倍”我觉得有“上涨了3倍”或“翻了3番”之说“翻倍”这个词合乎语法吗? Kpu材料用什么处理剂粘性好? 替换单词 句意不变 The dress is fine .I will ____ (buy) it.(what)______ about this red dress?It is nice.How many bottles do you _______(want).Two bottles ,piease.根据句意及首字母提补全单词Is that a_____.No,I need some eggs,too.Wha 顶径公差代号是什么意思 我想问一下Are his arms long的肯否回答是什么 “Textbooks Should be Recycled?”关于这个题目的英语作文 园林的概念? 粘性大,湿度大,易结块的食品原料用什么样的输送机好 Textbooks should be Recycled 像这种题目作文怎么写? CF穿越火线救世主拿的是什么枪?我说从佣兵中选出来的那人拿的咖啡色的啥枪? his arms are long改为否定句 Texbooks Should be Recycled?为题写一篇100字的英语作文 cf救世主的枪所有新枪的价格 是价格 不要搞错 长春公园据说面积是67hm2,这是什么意思?是多少平米? 题目text book should be recycled?字数越多越好 CF救世主的枪叫什么 精确度最高的数 下面的数,精确度最高的数是()a.4.5 b.4.50 c.4.500 作文,以textbook should be recycled为题说说建议之类的dui明天要交 不像你,而像他,这个说法正确吗 园林里德红线是什么意思啊 my husband has a favorite saying:"a bargain is bargain when you don't buy it"._(1 therefore2yet 3instead4besides_) he sets aside his simple ways when we dine out.His relatives always enter a restaurant with calculators to make sure they never __ 法国两男子晚间持械抢劫 得价值70万日本参议员当面向天皇递书信 官房长官日本政府将向救童中国留学生颁发感谢信东京地铁举行演习训练 防备首都直下型纽约再推控烟新政 将购烟年龄下限提高纽约遭飓风袭击一周年 数千灾民仍无家小猫将斗牛犬尾巴当做逗猫棒玩 网友直土耳其欧亚海底铁路隧道运营第一天就突76件日本国家重要文化财产下落不明 日本一男子弑母弃尸 藏尸冰箱月余终败美在联合国驻地部署情报人员 拦截各国英国一教师对学校过敏 不能摸文具数据显示日本近5年间借智能手机偷拍案阿姆斯特丹应对土地资源不足兴建水上住恐怖梦游:女子睡梦中自残 醒后发现全中国载人空间站命名“天宫”货运飞船为新华网:织牢保障困难群众基本生活的“长沙机场再受“诈弹”威胁 公安部门正韩国海域15日沉船事故一失踪中国船员美国警察向手持玩具枪男孩10秒内连开大图们江倡议协商会力促区域合作司法改革试点工作正式启动宝山馨华苑70多户遭窃? 小区摄像头(上接第一版)驱逐美国情报官员德外长:正确且必要开始6天拉美之行普京到访“美国后院”(上接第一版)成长励志真人秀《我们一起来!》 姚明项目刚一落地服务全部跟上打造亚洲最大的冷冻冷藏中转港台湾太平岛扩建有望提前完工 将可停3张春贤主持召开自治区党委常委会议 研张柏芝、邓萃雯等香港聚首 美艳合照曝伊拉克库尔德武装趁国内动乱之机夺占两历史问题,是日本的死穴(国际论坛)机舱突现鳄鱼致乘客惊慌 机头过重下坠西藏的石头和天空的光芒高原神龙中国梦 西藏故事 你我共奋进爱上《我的墨脱》纽约接连发生中餐馆老板遭抢劫事件 手援藏礼赞
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘