利用 GCD 提供的 dispatch_async
方法在并发队列中执行任务时, 其任务的执行顺序以及并发数量不可控, 想要实现并发控制的解决方案其实有很多. 比如使用 NSOperationQueue
的 maxConcurrentOperationCount
属性可以控制 NSOperation
中同时执行任务的最大数量. 下面我们来看看再 GCD 中的解决方法
dispatch_semaphore
我们先来看看有关 dispatch_semaphore
的三个方法.
|
|
利用 GCD 提供的 dispatch_async
方法在并发队列中执行任务时, 其任务的执行顺序以及并发数量不可控, 想要实现并发控制的解决方案其实有很多. 比如使用 NSOperationQueue
的 maxConcurrentOperationCount
属性可以控制 NSOperation
中同时执行任务的最大数量. 下面我们来看看再 GCD 中的解决方法
我们先来看看有关 dispatch_semaphore
的三个方法.
|
|
选择与你公司、应用程序或者皆有关联的名称作为类的前缀,并在代码中均使用这一前缀。
若自己所开发的 App 使用到第三方库,则应为其的名称加上前缀。
如果创建类实例的方式不止一种,那么这个类就会有多个初始化方法。不过要在其中选中一个作为全能初始化方法,并做到其他初始化方法都调用它。
使用 @property 语法来定义对象中所封装的数据。
通过 assign strong weak copy unsafe_unretained
定义存储数据所需的正确语义。
开发 iOS 程序时应该使用 nonatomic
属性,因为 atomic
属性会严重影响性能。
在对象内部读取数据时,应该直接通过实例变量来读,而写入数据时,则应该通过属性来写,以确保其声明的内存管理语意。
在初始化和 dealloc
方法中,总是应该直接通过实例变量来读取数据。
在使用惰性初始化时,需要通过属性来读取数据。
对象等同性
这一概念。如果想检测对象的等同性,可提供 NSObjcet
协议中的 isEqual
和 hash
方法。
相同的对象一定拥有相同的哈希码,但是两个哈希码相同的对象却未必相同。
不要盲目选择逐个检查每条属性,而是应该依照具体需求来定制方案,比如可以使用唯一的 identifier
来对比检查两个对象是否相等。
编写 hash
方法时,应该使用计算速度快而且哈希码碰撞几率低的算法。
因为好久没写 OC 代码了,回头重看 《Effective Objective-C 编写高质量 iOS 与 OS X 代码的 52 个有效方法》,总结一些 OC 编码时的技巧。
一般来说,应再某个类的头文件中使用向前声明来提及某个类,并在实现文件(.m)中引入那些类的头文件,以降低类之间的耦合。
当无法使用向前声明时,比如要声明某个类遵循某个协议。在这种情况下,尽量把该类遵循某协议
的声明移入class-continuation 分类
中。如果不行的话,就把某协议单独放在一个头文件中,然后将其引入。
与常规方法相比更加简明。同时,如果值中有 nil,则会抛出异常,方便定位问题。而使用常规方法遇到 nil 会自动结束向集合添加数值。
在自己实现的项目中需要隐藏掉 UINavigtionBar 底部的实线, 并在底部添加一个外观一样的 UIView, 用来实现为 NavigationBar “增高”的功能. 之前在 iOS9 中使用的方法失效了. Google 了一下找到的通用的办法.
我们将这个功能写在 UINavigationController
的 extension 中. 首先利用简单的递归找到底部那条实线.
|
|
自已项目中需要使用一个类此为 iTunes 中音乐评星的功能. 在 gihub 中找了一些发现都太繁琐. 本着一切从简, 能自己动手就自己动手的原则, 就参照开源的实现自己写了一个.
先来看看图片中我们要实现的控件.
这个 StarRatingView
有两种状态, 分别是可编辑和不可编辑的状态. UI结构是一个 baseView 中拥有 5 个 UIImageView
, 根据用户手指的移动 CGPoint
, 为相应的 UIImageView
填充高亮或普通的 star 图片.
当 tableView 或 collectionView 的数据发生变化时,我们需要自己来处理控制器的刷新行为,比如reloadData
insertRowsAtIndexPatch
等刷新方法。我们很可能会使用到枚举或if else
进行逻辑判断。在阅读 Yep 代码的时候发现了一种利用 extension
的方法,可以让控制器中的代码更加简洁。
我们首先为 UITableView 创建一个 extension, 并创建一个 enum 用来表示 tableView 的所有刷新行为。
|
|
在 iOS 开发中我们会经常使用到 UIAlertController
, 但本身提供的 API 接口有限, 自定义外观会非常麻烦, 更别提在其中使用自定义的 View 了. 今天我们来封装一个 ActionSheetView
, 用来代替系统提供的 actionSheet
类型.
图中底部弹出的菜单就是我们要实现的 ActionSheetView
, 它有的主体结构是由一个 UITableView
来实现, 我们可以为其定制非常多种类的 UITableViewCell
, 并通过 Swift 中的枚举关联值的特性,让其外部使用变得非常简单. 比如下面这种拥有 switch 开关的 cell.
在进行 App 内部搜索或者筛选网络加载的 String 内容时, 需要对字符串进行过滤. 比如我们有一个 textField 让用户在此输入 nickName, 他或许会调皮的输入一堆空格. 这时候就需要我们对用户的输入进行检查, 符合标准才能通过. 下面我们为 String 类型增加一个 extension 完成这样的功能.
首先定义一个 enum, 用来表示不同的过滤规则.
|
|
在学习 iOS 开发初期的时候从一些技术大牛的文章中了解到 Vim 这个神器, 却因为学习成本过高, 屡次尝试屡次放弃. 直到某一天在 YouTube 上搜索到了一个叫做 Learning Vim in a Week 的讲座, 短短的20分钟视频让我迅速上手了 Vim. 视频中不仅仅介绍了 Vim 的组合键的应用场景. 还提到了一个非常实用的技巧: 利用 Karabiner
这款映射键盘的软件配置按键重复触发的延迟, 来让 hjkl
这些控制光标的操作如闪电般迅速. 经过反复观看视频, 大概一周左右的磨合, 就可以做到 break up with your mouse
了.
开发中我们通常在 App 长时间加载某些数据的时候需要展示 HUD 视图,告知用户当前 App 的状态。Apple 为我们提供了 UIAlertView
UIActivityView
方便我们在必要的时候提醒用户。 但通常它们提供的 API 无法让我们做针对性的自定义,今天我们来实现一个简单的自定义 HUD。
首先我们先看一下在 App 中的实际运行效果。
结构非常简单: 一个灰色半透明的 UIView
和一个 UIAvtivityIndicatorView
.
UITableView
与 UICollectionView
无疑是 iOS 开发中使用最多的视图控制器,它往往负责展示大量的数据. 伴随着用户的手指不断的滑动,系统会反复刷新UI, 加载所要展示的内容。而一旦数据体积增大,计算的逻辑复杂,就会造成过多的性能浪费。解决这类问题的方法有很多. 最近在 Yep
代码中看到的方法,在应用到自己项目的时候感觉非常不错, 所以有了以下的记录总结.
首先看一下 Demo 要实现的效果
Xcode 的代码提示是没有办法验证字符串 (如: “Tychooo”) 的输入正确的, 我们在使用 storyboard 创建 UI 时, 经常会使用到 segue 的 identifier 来进行 viewController 跳转. 对其进行封装, 可以很好的减少自己手残输入错误时 debug 的时间成本. 我们一起来看一下 WWDC 中的 Demo.
我们首先定义一个协议 SegueHandlerType
, 之后凡是需要用的 segue 跳转的 viewController 都需要循序此协议.
|
|
|
|
在实现类似与微博或者微信的 timeline
功能时, 往往需要在 UITableViewCell
中利用 UIImageView
展示单张或多张图片, 这些图片的来源通常都是网络. 而一旦网络速度不稳定, cell 中的 imageView 异步加载图片的过程就会一直显示 backgroundColor. 用户对图片正在下载的情况全然不知. 而像 SDWebImage
和 Kingfisher
这样的第三方框架很好的解决了这种问题: 一方面可以显示一张 placeholderImage, 也可以显示一个 UIActivityIndicatorView
让用户感受到下载的进程.
而实现 activityIndicatorView 的方法又有很多种, 我第一个想到的就是自定义一个 UIView
, 在里面添加一个 UIImageView
和 一个 UIActivityIndicatorView
. 之后使用这个自定义的 view 就可以很好的完成任务. 而最近我在使用 Kingfisher
时, 发现它利用 分类 的功能结合 runtime 的特性, 直接为 UIImageView
添加一个 indicatorView 的实例变量.
通过 分类 -> extension 不能添加新的实例变量, 但我们可以利用 runtime 的 Associated Objects 来弥补这一不足.
作为一名刚刚入门 iOS 开发的人来说,理解并熟练使用 Auto Layhout 非常重要。开始接触自动布局是非常困难和复杂的,布局一个视图通常需要添加非常多的约束constraints
,尤其是在创建动态视图时,我们要不断的重复添加和删除约束以达到我们想要的效果。而使用 Stack View
可以很大程度上简化我们频繁调试约束的过程。
通常,我们在创建用户界面的时候很多视图是程线性
排列的。以下面这个界面为例,界面中包括非常多的子视图UILabel
,它们是垂直vertically
线性排列的。
在 iOS 开发使用 Swift 时, 经常会遇到需要调用Objective-C
类方法的情况,苹果已经将几乎所有的Objective-C
的API都已经无缝的转接到了 Swift,同时一些特别的类型也做了桥接,桥接意味着可以随意进行转换。
利用这种括弧 + as
的方法可以直接调用Objective-C
的方法, 同时实现了自动的类型转换,比如上面的例子,lenght
是NSString
的方法, 我们可直接在一行代码中将String
转换成NSString
并调用其方法。
笔记信息的来源大部分来自课程随堂的Keynote,以及一些我个人的看法,因为没有软件开发的基础,难免容易混淆一些基础概念,还请各位看官斧正。
这节课主要介绍了在 iOS 开发中经常使用的结构类型,呈现了一些 Swift 语言的一些基础特性,更详细的语法和特性,还是需要仔细阅读苹果官方的The Swift Programming Language
来了解的。
前两天无意间看到一个部署 Octopress 的教程, 今天终于抽出时间折腾了一下.
因为对 Git、Rudy 和 HTML 没啥了解,遇到很多问题,所以先把今后可能用到的语法总结一下。
Octopress文档链接
|
|
|
|
在 iOS 中包括下列几种手势识别,方便我们自定义一些与用户交互的操作方式。
###1.UIPinchGestureRecognizer
两个手势放大或缩小,Pinch
手势传递的是比例,不是坐标。
当手势开始的时候,比例是 1
|
|
###2.UIRotationGestureRecognizer
两个手指的手势,在一个圆周上转动。就像一个旋转的按钮。他会告诉你旋转了多少弧度retation
|
|