iOS 技术栈

Swift

defer

func anyfunction() {
    defer {
        print("Handle 1")
    }
    defer {
        print("Handle 2")
    }
    print("any func exit")
}
anyfunction()

guard if let

var v1: String? = "v1"
var v2: String? = "v2"
if let v11 = v1 ,
    let v22 = v2 {
    print(v11,v22)
}

func test(parameter:String?) {
    if let para = parameter,
        let url = URL(string: para) {
        print(url)
    }

    guard let para = parameter, let url = URL(string:para) else {
        return
    }
    print(url,para)
}
test(parameter: nil)
test(parameter: "http://")

try do catch

enum OperateType: Error {
    case noParameter
    case emptyParameter
}
func operate(parameter: String?) throws -> String {
    guard let para = parameter else {
        throw OperateType.noParameter
    }
    if para.characters.count > 0 {
    } else {
        throw OperateType.emptyParameter
    }
    return para.lowercased()
}

do {
    try operate(parameter: nil)
} catch {
    print("some error")
}

do {
    try operate(parameter: nil)
} catch let error {
    print(error)
}

do {
    try operate(parameter: nil)
} catch OperateType.noParameter {
    print("缺少参数")
} catch OperateType.emptyParameter {
    print("空白参数")
}

try? operate(parameter: nil)

属性观察(Property Observers)参考

public class A {
    //存储属性
    private var _a:String
    //计算属性,只是提供 set 和 get 两种方法
    public var a:String {
        set {
            _a = newValue
        }
        get  {
            return _a
        }
    }
}
public class B:A {
    //对父类的属性任意地添加属性观察,而不用在意父类中到底是存储属性还是计算属性
    public override var a:String {
        didSet {
            print _a
        }
    }
}

final 对性能的影响参考

尾递归

递归调用都需要在调用栈上保存当前状态,否则我们就无法计算最后的n,当 n足够大,调用栈足够深的时候,栈空间将被耗尽而导致错误,也就是我们常说的栈溢出了。

func sum(n: UInt) -> UInt {
    if n == 0 {
        return 0
    }
    return n + sum(n - 1)
}
sum(4) // 10
sum(100) // 5050

尾递归就是让函数里的最后一个动作是一个函数调用的形式,这个调用的返回值将直接被当前函数返回,从而避免在栈上保存状态。

Objc

@property

  1. 基本数据类型默认关键字是atomic,readwrite,assign

  2. 普通Objective-C 对象atomic,readwrite,strong

  3. nonatomicatomic

    • nonatomic禁止多线程变量保护,提高性能

    • atomic 默认, 提供多线程安全

      {lock}
      if (property != newValue) {
        [property release];
        property = [newValue retain];
      }
      {unlock}
      
  4. assign,strong,copy

    • assign对基础数据类型(NSIntegerCGFloat)和C数据类型(int, float, double, char)等,Non-ARC下,assign是一个property的默认属性,无论简单数据类型,还是指向对象的指针
    • strong表着这个property应该持有它所指向的对象, 不能修饰简单数据类型的property
    • copy的property被赋值,应该是原有对象的一份拷贝,只有实现了NSCopying协议,并且实现了其中的copyWithZone:方法的对象才能被拷贝, 并不是所有的拷贝都产生了新的对象(比如NSString)
    • weak为property生成__weak所有权修饰符
    • unsafe_unretainedassign等价
    • retainstrong等价

copy & metableCopy

非集合类对象的copy操作 集合类对象的copy操作
[immutableObject copy] // 浅复制 [immutableObject copy] // 浅复制
[immutableObject mutableCopy] //深复制 [immutableObject mutableCopy] //单层深复制
[mutableObject copy] //深复制 [mutableObject copy] //单层深复制
[mutableObject mutableCopy] //深复制 [mutableObject mutableCopy] //单层深复制

单层深复制: 集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制

iOS Framework

  1. All official iOS framework
  2. 常用的:
    • Foundation.framework
    • UIKit.framework
    • QuartzCore.framework
    • JavaScriptCore.framework
    • WebKit.framework
    • CFNetwork.framework
    • MapKit.framework
    • Metal.framework
    • OpenGLES.framework
    • SpriteKit.framework
    • Photos.framework
    • ImageIO.framework
    • CoreText.framework
    • CoreLocation.framework
    • CoreImage.framework
    • CoreBluetooth.framework
    • CoreGraphics.framework

Foundation

  1. NSException

    种类:

    • 语法和数理上的问题,如 index out of range, 1/0.0, sqrt(-1),unsigned
    • Crashed: NSOperationQueue 等线程安全问题
    • EXC_BAD_ACCESS KERN_INVALID_ADDRESS访问已释放对象,引用问题问题weakSelf解决
    • Fatal Exception: NSInvalidArgumentException unrecognized selector sent to instance 如 array.color, array没有color属性或方法,OC动态特性的缺陷,增强类型解决(isKindofClas, NSArray, id, s)
    • Crashed: com.apple.root.default-qos SIGABRT ABORTGCD并发线程超过64个,线程质量问题
  2. RunLoop

    • 用于周期性的不退出的任务
    • 一个线程一个runloop, 默认不获取时不创建
    • main RunLoop 负责自动释放池、延迟回调、触摸事件、屏幕刷新等功能
    • 在异步处理情景吓常用,如CGD的dispatch_asyncAFNetworking后台下载 和AsyncDisplayKit后台渲染 (发现AsyncDisplayKit跟我的后台线程渲染原理一致)

UIKit

  1. 类继承关系

    NSObjctUIRespnder
        │    ├UIView
        │    │    ├UIWindow
        │    │    ├UILabel
        │    │    ├UIImageView
        │    │    ├UIWebView
        │    │    ├UITableViewCell
        │    │    ├UIActionSheet
        │    │    ├UIAlertView
        │    │    ├UISearchBar
        │    │    ├UITabbar
        │    │    ├UINavigationBar
        │    │    ├UIActivityIndicatorView
        │    │    ├UIProgressView
        │    │    ├UIPickerView
        │    │    └UIScrollView
        │    │        ├UITextView
        │    │        └UITableView
        │    ├UIApplication
        │    └UIViewControllerUIControl
        │    ├UIDatePicker
        │    ├UIPageView
        │    ├UISegmentedControl
        │    ├UITextField
        │    ├UISlider
        │    └UIButtonCALayer
    
  2. UIView结构

    UIView
        ├布局(frame, bounds)和subviews管理
        ├UIWindow
        │    ├提供一个区域来显示UIView
        │    ├将事件分发给其他对象
        │    └与UIViewController协同工作,完成设备方向旋转的支持
        ├UIRespnder
        │    └事件处理
        └CALayer
    
  3. layoutSubviews被调用情景

    • init初始化不会触发。
    • addSubview
    • 设置了不同的frame
    • 滚动一个UIScrollView
    • 调用setLayoutSubviews
    • 旋转Screen会触发父UIView上的layoutSubviews
    • 改变一个UIView的frame大小会触发父UIView上的layoutSubviews
  4. drawRect被调用情景:

    • 初次没有rect, Controller->loadView, Controller->viewDidLoad触发
    • sizeToFit
    • contentMode属性值为UIViewContentModeRedraw时,每次frame变化
    • 调用setNeedsDisplay或者setNeedsDisplayInRect
  5. 事件响应优先级

    第一响应者(view) > 下面的响应者 > cntroller > application

  1. UIViewController
  2. 负责创建其管理的视图及在低内存的时候将他们从内存中移除。还为标准的系统行为进行响应。
  3. 管理所有UIView的层次结构,并响应设备的方向变化。

  4. UIWindow

    一般应用程序只有一个UIWindow对象,可以手动创建多个添加到程序中, 只有一个UIWindow可以接受到用户的触屏事件

  5. UIScreen

       iphone屏幕分辨率:
       iphone4前的设备:320*480
       iphone4和4s:640*960
       iphone5和5s:640*1136
       iphone6:750*1334
       iphone6p:1242*2208
       ipad   ipad2:1024*768
       ipad3和4  ipad4:2048*1536
       ipad mini:1024*768
    

数据存储方式

  • Preference(偏好设置NSUserDefaults
  • Property List(Plist文件 NSArray\NSDictionary)
  • NSCoding(NSKeyedArchiver\NSkeyedUnarchiver)
  • SQLite
  • Core Data

NSUserDefaults Plist都是文本文件,不适合大文件

Plist

  1. 存储位置 包括工程里(只读?)和沙盒(续写)

  2. 读写方式:

   // 工程
   NSString *path = [[NSBundle mainBundle] pathForResource:@"provinces" ofType:@"plist"];  
   // or 沙盒 Document、Library、Caches、tmp
   NSArray *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"provinces.plist"]; 

   // 读取到文件(NSArray,NSDictionary...)
   NSMutableArray *array = [NSMutableArray arrayWithContentsOfFile:path];

   // 添加数据&写入数据
   [array addObject:[NSMutableDictionary new]];
   [array writeToFile:path atomically:YES];

算法

排序算法

  • 选择排序

    1. 暂定第一个元素为最小元素,往后遍历,逐个与最小元素比较,若发现更小者,与先前的"最小元素"交换位置。达到更新最小元素的目的。
    2. 一趟遍历完成后,能确保刚刚完成的这一趟遍历中,最的小元素已经放置在前方了。然后缩小排序范围,新一趟排序从数组的第二个元素开始。
    3. 在新一轮排序中重复第1、2步骤,直到范围不能缩小为止,排序完成。

  • 冒泡排序

    1. 在一趟遍历中,不断地对相邻的两个元素进行排序,小的在前大的在后,这样会造成大值不断沉底的效果,当一趟遍历完成时,最大的元素会被排在后方正确的位置上。
    2. 然后缩小排序范围,即去掉最后方位置正确的元素,对前方数组进行新一轮遍历,重复第1步骤。直到范围不能缩小为止,排序完成。

  • 插入排序

    • 从一个乱序的数组中依次取值,插入到一个已经排好序的数组中

    • 开始时前方有序区只有一个元素,就是数组的第一个元素。然后把从第二个元素开始直到结尾的数组作为乱序区。

    • 从乱序区取第一个元素,把它正确插入到前方有序区中。把它与前方无序区的最后一个元素比较,亦即与它的前一个元素比较。
      • 如果比前一个元素要大,则不需要交换,这时有序区扩充一格,乱序区往后缩减一格,相当于直接拼在有序区末尾。
      • 如果和前一个元素相等,则继续和前二元素比较、再和前三元素比较......如果往前遍历到头了,发现前方所有元素值都长一个样的话(囧),那也可以,不需要交换,这时有序区扩充一格,乱序区往后缩减一格,相当于直接拼在有序区末尾。如果比前一个元素大呢?对不起作为有序区不可能出现这种情况。如果比前一个元素小呢,请看下一点。
      • 如果比前一个元素小,则交换它们的位置。交换完后,继续比较取出元素和它此时的前一个元素,若更小就交换,若相等就比较前一个,直到遍历完成。
    • 往后缩小乱序区范围,继续取缩小范围后的第一个元素,重复第2步骤。直到范围不能缩小为止,排序完成

  • 快速排序 平均Ο(nlogn),最坏Ο(n2)

    • 原始的快排。
    • 为制造适合高效排序环境而事先打乱数组顺序的快排。
    • 为数组内大量重复值而优化的三向切分快排。

    • 从数列中挑出一个元素,称为 “基准”(pivot),

    • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
    • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

  • 堆排序 平均Ο(nlogn)

  • 归并排序

查找算法

  • 二分查找算法
    • 在有序数组中查找某一特定元素的搜索算法
  • BFPRT(线性查找算法)

搜索

  • DFS(深度优先搜索)
  • BFS(广度优先搜索)
    • Dijkstra算法

其他

  • 动态规划算法
  • 朴素贝叶斯分类算法

results matching ""

    No results matching ""