知识点

作者: 桃逸 | 来源:发表于2016-10-23 11:47 被阅读20次

    参考:
    Apple Developer
    Apple OpenSource

    1. 基础知识点:

    Cocoa Touch

    是apple基于手机触摸的一套基础框架,包括音频视频,数据管理,网络,用户应用等框架;
    查看官方文档说明

    >> runtime运行时原理

    runtime是一套比较底层的纯C语言API,我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runtime的C语言代码;
    利用runtime机制让我们可以在程序运行时动态修改类、对象中的所有属性、方法;
    用处:

    • 动态创建一个类;
    • 动态为某个类添加属性\方法,修改属性值\方法;
    • 遍历一个类的所有成员变量(属性)\所有方法 例如:我们需要对一个类的属性进行归档解档的时候属性特别的多,这时候,我们就会写很多对应的代码,但是如果使用了runtime就可以动态设置;
      相关函数:
    • objc_msgSend : 给对象发送消息
    • class_addMethod: 添加方法
    • class_copyMethodList : 遍历某个类所有的方法
    • class_copyIvarList : 遍历某个类所有的成员变量
      IOS的函数调用是在运行时通过objc_msgSend决定的;
    GCD (Grand Central Dispatch)

    GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节;
    常用函数:
    dispatch_async dispatch_group_async dispatch_barrier_async dispatch_apply

    APNS (Apple Push Notification service)

    APNS的消息注册跟消息吹都在AppDelegate中处理,使用:
    didRegisterForRemoteNotificationsWithDeviceToken
    didReceiveRemoteNotification
    相关application函数;

    工作原理:

    • 应用注册,由iOS系统向APNS请求返回设备令牌;
      (void)application:(UIApplication )application didRegisterForRemoteNotificationsWithDeviceToken:(NSData)deviceToken;
    • 应用程序接收到设备令牌并发送给服务器;
    • 服务器把要提送的内容和设备发送给APNS;
    • APNS根据设备令牌找到设备,再由iOS根据APPID把推送内容展示;
    NSZone

    可以想象成一个内存池,alloc与dealloc这些操作,都是在这个内存池中操作的,cocoa总是会配置一个默认的NSZone,任何默认的内存操作都是在这个zone上操作的;
    默认的NSZone是全局的,时间一长,必然会导致内存碎片化,如果大量的alloc一些object,那么性能就会收到影响;所以cocoa提供方法,你可以自己生成一个NSZone,并将alloc,copy全部限制在这个zone之内;

    >> 数据存储

    >> 沙盒

    http://www.cnblogs.com/luckhao/p/5437896.html
    沙盒目录结构

    Paste_Image.png
    文件存储
    • plist 存储
      存放一些基本数据类型的数据,一般在Document目录下,plist路径获取代码示例:

    NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
    NSString *fileName = [path stringByAppendingPathComponent:@"123.plist"];

    • 偏好设置存储
      偏好设置是专门用来保存应用程序的配置信息的,一般不要保存其他安全性数据;
      如果要立即同步数据到文件,使用synchronize;
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults synchronize];
    

    偏好设置会将所有数据保存到同一个文件中。即preference目录下的一个以此应用包名来命名的plist文件;

    • 归档操作 NSKeyedArchiver
      归档在iOS中是另一种形式的序列化,只要遵循了NSCoding协议的对象都可以通过它实现序列化;
      保存文件的扩展名可以任意指定;
    数据库存储:
    1. SQLite 轻型嵌入式关系数据库,包含在一个相对小的c库中,基于C的API操作;
    2. CoreData:对象关系映射(ORM),它将数据库的创建,表的创建,对象与表的转换操作等封装起来,简化了我么的操作;开发者只要把模型搭建起来,具体数据库如何创建不用管,在IOS项目中添加“Data Model”文件;
    3. 第三方架构FMDB: 相比于SQLite3来说Core Data存在着诸多优势,它面向对象,开发人员不必过多的关心更多数据库操作知识,同时它基于ObjC操作,书写更加优雅等。
    多线程访问数据同步?
    • NSLock
      常用函数 lock,unlock;

    • NSCondition
      A condition object acts as both a lock and a checkpoint in a given thread. 即它表示一个锁+一个线程检查器,线程检查器主要是根据条件决定是否继续运行线程,即线程是否被阻塞;
      常用函数:
      lock,unlock
      wait:等待其他线程发出信号,此时其他线程可访问lock区域内的内容,wait相当于在调用时候unlock了,然后触发后再次lock,所以wait时候其他线程可以访问lock的内容;
      signal: 处理完数据通知其他线程

    • 互斥锁 synchronized
      使用 @synchronized(锁对象) {} 锁住一块代码操作;
      能有效处理多线程数据安全问题,但是消耗大量CPU资源;

    • DSP中的信号量 dispatch_semaphore_t
      使用函数:
      dispatch_semaphore_create(num) //创建信号量的初始值
      dispatch_semaphore_wait 信号量-1,如果等于0则阻塞,大于0往下执行;
      dispatch_semaphore_signal 信号量+1

    • CoreData的多线程访问同步?

    OC与Swift混编
    • Swift访问OC
      使用 Bridging Header,加入oc文件时系统询问自动创建,或者自己手动创建,在项目中加入一个新的头文件命名为"项目工程名-Bridging-Header",然后再设置Build Setting->Swift Compiler ->Object-C Bridging Header的路径,必须只想文件本身;
      在这个头文件中添加swift需要访问的OC类的头文件;
    • OC访问Swift
      需要配置 Build Setting下的 Packaging:
      设置Defines Module为YES,设置Product Module Name,在调用swift
      的模块中加入该名称的"***-Swift.h"头文件(这个文件是系统自己创建的),就能够直接使用OC语法调用swift模块;

    后台多任务管理机制

    http://www.zhihu.com/question/21192280

    Paste_Image.png
    响应链

    系统会根据hittest来处理将定位消息属于具体哪个窗口;
    能响应对象的都是UIResponse的子对象;
    app接受的响应会逐级传递寻找响应, 形成一个响应链,例如一个事件响应链:
    AppDelegate --> UIApplication --> UIWindow --> UIViewController --> UIView --> UIButton
    使用nextResponder函数可以循环获取父级响应对象;
    用户的一个点击事件信息包括:UITouch和UIEvent;

    keychain(Security.framework)

    它是一个在所有app之外的sqlite数据库;
    Keychain的信息是存在于每个应用(app)的沙盒之外的,所以keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效,数据还在;
    NSUserDefaults存储是不安全的,简单的信息存储使用NSUserDefaults即可,但是对于安全性要求比较高的信息,比如账户密码等;
    基本函数:SecItemAdd/SecItemUpdate/SecItemCopyMatching/SecItemDelete

    100个知识点汇总
    http://www.csdn.net/article/2015-01-19/2823604-ios-interview-questions

    类的load与initialize静态函数作用

    这两个静态方法是可选的,且只有在实现了他们时才会被调用;

    • load的作å用
      当类对象被引用项目中,runtime会向每一个类对象发送load消息,这个消息只会被调用一次,要想修改原来类方法及其他,可以在分类的load中进行实现;
    • initialize作用
      在整个runtime中也只调用一次,但是它是该类的第一个方法调用之前调用的,用于确保实例初始化前某些条件必须满足;

    2. 内存与多线程知识点

    多线程

    内存管理
    http://www.jianshu.com/p/dba7e8010cd3
    自动释放池块与线程
    使用局部自动释放池块降低最大内存占用率

    • 为什么更新UI都在主线程中进行?
      因为UIKit不是线程安全的,无法保证多个线程对同一UI的更新操作;
      在子线程中是不能进行UI 更新的,我们看到的UI更新其实是子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新。

    3. UI知识点:

    Core Animation / Core Graphics
    • Core Animation iOS 系统基本渲染框的OC语言框架
      基于CoreGraphics的OC语言封装动画处理架构;
      动画执行过程都是在后台操作的,不会阻塞主线程;
      动画使用:
    CALayer *layer = [CALayer layer];
    CABasicAnimation *animation = [CABasicAnimation animation];
    animation.keyPath = @"transform.scale";
    animation.toValue = @0;
    [layer addAnimation:animation forKey:nil];
    

    CA动画基础参考:http://www.jianshu.com/p/8c1c1697c0ce

    • Core Graphics 是底层绘制的C语言框架
      实际用到的CG开头的函数与变量是指这绘制库;
      可在drawRect函数中重绘视图,也可对图形图片进行切角,旋转等转换处理;
    CGContextRef context = UIGraphicsGetCurrentContext();  
    NSString *str1 = @"画线";  
    [self drawText:str1 atPoint:CGPointMake(20.0, 20.0) FontSize:15];
    CGContextScaleCTM(context, 1.0, -1.0);  
    CGContextSaveGState(context);
    CGContextRestoreGState();
    

    每一个 UIView 都有一个 graphics context (绘图上下文),在设备硬件显示前,绘制的所有视图都会被渲染到这个上下文中;
    iOS 在任何时候需要更新视图都是通过调用 drawRect 方法;
    参考学习:http://www.tuicool.com/articles/jaM7zmN

    UIView本身更像是一个一个CALayer的管理器

    把UIView看做图片的话,layer就像是一个图层,一个图片是由很多个大小不同的有层次的图层构成的 uiview也是

    UITableView 复用机制

    UITableview通常只会显示当前页面最大可显示cell个数加1,cell离开屏幕后会从队列中删除;

    • 复用队列
      只有cell被滑出当前页面的时候,此cell才会被加到复用队列中,使用dequeueReusableCellWithIdentifier,如果找不到才会调用UITableviewCell的initWithStyle:reuseIdentifier接口创建cell
    imageNamed

    使用imageNamed方法创建UIImage对象时,图片会自动加载到系统缓存中不再释放,会使内存增大

    UIImageView圆角

    如何提高调价圆角的性能?

    • 一般使用clipsToBounds与layer.corneRadius, 但是这个方法会强制Core Animation提前渲染屏幕的离屏绘制,为性能带来负面影响;
    • 使用贝塞尔曲线切割图片

    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
    [[UIBezierPath bezierPathWithRoundedRect:RECT cornerRadius:RADIUS] addClip];
    [image drawInRect:RECT];
    UIImage* imageNew = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();

    key window是?

    可接收键盘输入等事件的UIWindow,官方文档如是说:
    The key window is the one that is designated to receive keyboard and other non-touch related events. Only one window at a time may be the key window.
    使用 makeKeyAndVisible让一个 UIWindow 变成 key window;
    程序主窗口是:[[[UIApplication sharedApplication] delegate] window];

    pushViewController 与 presentViewcontroller
    • pushViewController提供的是一个栈控制器数组;
    • presentViewcontroller提供的是模态视图控制器;
      模态是指一个控制器present另一个控制器,prensenting 与 presented,两者通过delegate实现交互;所以在没有navigationController的情况下,使用presentModalViewController能进行controller间的转换;

    相关文章

      网友评论

          本文标题:知识点

          本文链接:https://www.haomeiwen.com/subject/didusttx.html