SlideShare ist ein Scribd-Unternehmen logo
1 von 36
Obj-C/iOS 入门分享




 搜索与算法 – 主搜索引擎技术 霜天
第一部分 Obj-C基础语法与用法

WHAT IS OBJ-C
概述

• OC是c语言的超集
 – OC是编译语言,不是解释语言,同时也是动态语言。
   • Runtime控制了线程切换,消息队列,事件分发等。
   • 类的数据结构 支持了函数动态查找,内存申请等。
   • 所谓的关键字其实就是一些typedefine。甚至更简单。


 – OC最牛的地方是拥有解释语言的灵活,拥有编译语言的效率。
   • 拥有像java一样完善的类库。
   • 拥有像python一样的元类。
   • 函数调用被解释为一种类似查表的操作,简单高效。
文件名

– .xcodeproj
    • 工程文件,是个文件夹,里面定义了整个工程的文件关系。
– .pch
    • 预处理文件,类似于define.h之类的,定义一些公用的宏。
– .xib
    • 界面文件,里面定义了界面的定义,例如坐标,颜色,字体等。
– .h
    • 头文件。
– .m
    • Object-c文件,只能出现oc语法。
– .mm
    • 支持oc/c/c++语法,可以混编。
– .framework
    • 框架包,依赖包,一个文件夹,包含.h文件和.lib文件。
基础定义

• Obj-C特有的关键字
  – Class
     • 类指针,和c里的class不同,这是一个类型关键字,Class class定义一
       个通用的类
  – Id
     • 对象指针,可以向像这样 id class2 = class,来指定一个指向class的指
       针
  – SEL
     • 函数名称,这个在后面会介绍c定义,SEL selector = @selector(func) 这
       种定义函数的语法在Obj-C里很常见
  – IMP
     • 这个不太常出现,这是c里面的函数指针,IMP func = [class function] ,
       然后就可以这样调用func()
基础定义

• 类 与 接口
  – @interface CLASS_NAME: SUPER_CLASS_NAME <PROTOCAL>;
     • CLASS_NAME 定义一个类名。
     • SUPER_CLASS_NAME 继承的父类 。
     • PROTOCAL 实现的接口。
     Interface 的感觉就像 C++里面的 Class,一般写在.h里面
  – @implementation CLASS_NAME;
     • CLASS_NAME 的实现。
     Imolementation 的感觉就是.cpp里面的实现,一般写在.m里面
  – @protocal ;
     • 接口名称,一个类实现的接口,类似于java里面的interface。
基础定义

• 成员变量 与 成员函数
 – @property (optional args) MEMBER_NAME
    • MEMBER_NAME 是成员变量名称。
    • 你可以像c风格一样定义一个成员变量,也可以用property方式,这种
      方式的优点就是帮你生成 getter和setter方法。
 – -/+ (RETURN_TYPE)FUNCTION_NAME:arg1 COM:arg2
    • -/+ 分别代表了成员函数/类函数
    • 第一个参数前面是函数名称,第二个参数开始,每个参数前面是这个
      参数的一些注释。
    • 用参数注释起初很别扭,习惯以后,会发现这个注释很有用。
 – @selector(FUNCTION_NAME)
    • 函数变量,可以理解为c里面的函数指针。
比较一个简单的实例

• #C++                           #Object-C
  class Chinese: public People   @interface Chinese:People
  {                              {
      public:
        int age ;                         NSInteger* _age;
        void eat(char* food);
  }                              }
                                     - (void)eat:(NSString* )food;
                                 @end
第二部分 内存管理,消息队列简介

WHAT IS RUNTIME
内存管理介绍


– Retain/Release/Autorelease
    • 一个类alloc出来以后,引用计数就为1,每次retain,引用+1
    • Release既是引用-1,如果引用计数变为0,则由运行态调用类的
      dealloc函数回收内存
    • Autorelease是把一个类设定为自动释放类型,这种类的生存周期只有
      一次完整的事件循环,超出则自动放入自动释放队列autoreleasepool
      由系统自动release一遍。
消息管理介绍


– Runloop
   • 一般来说一个线程要拥有一个消息队列。
   • 消息队列中存储着这个线程要分发处理的消息。
   • 这些消息从何而来?一般从如下几个地方:
      a. 系统的点击,触摸事件。
      b. 网络响应。
      c. 时间阻塞的延迟响应。
不同的消息会由runloop的主线程负责分发给特定的
对象去执行相应的操作。
、
第三部分 iOS程序结构与模式

WHAT IS APP OF IOS
一个main函数的入口

#import <UIKit/UIKit.h>
#import "etao4iphoneAppDelegate.h"
int main(int argc, char *argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSLog(@"%@",NSStringFromClass([etao4iphoneAppDelegate class]));
  int retVal = UIApplicationMain(argc, argv, nil,
NSStringFromClass([etao4iphoneAppDelegate class]));
    [pool release];
    return retVal;
}
     从etao4iphone里面开始,才是代码的开始。
MVC介绍


– Model/ View/Controller
   • Model一般理解为数据的集合,负责获取数据,返回数据,存储数据。
   • View一般理解为事件的收集与结果的展现,负责捕捉到一个事件,同
     时负责把某些数据展现出来
   • Controller一般理解为逻辑的集合,负责控制什么样的事件去获取什么
     样的数据,并展现出来
经典的mvc结构:
view可以理解为鼠标键盘显示屏这样的传感器;
model可以理解为内存,网卡,硬盘;
controller就类似于cpu与程序逻辑。
代理机制介绍


– OC里广泛应用着代理机制:
  • 首先定义一个协议,这个协议包含了一些函数定义,但是没有实现,
    类似于c++里面的纯虚类,java里面的interface接口。
  • 某一个类A实现了这个代理所定义的函数。
  • 某一个类B,捕捉到了一些事件,它不知道该如何处理这个事件,它
    就把这个事件丢给满足协议的类A去处理。B就是A的代理。
代理模型介绍
                              感觉到了一个点击事件
类A实现了具体函数




     类A                          类B
 实现方法:                         捕捉到事件
 -(void)show


               协议定义了函数名


负责展现出来这个事件
                    协议
                -(void)show
KVC/KVO介绍


– KVC(Key-Value-Coding)/KVO(Key-Value-Observing):
   • OC内部所有的函数调用都被改写成obj_MsgSend函数,这个函数就是
     通过给定的函数名称去查找对应的类内部的函数地址。
   • KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。
     简单来说,就是一个通用指针,指针有一个成员叫isa(is a kind of),
     这个指针在0x00的偏移,指向这个对象具体的类型。
   • KVO是建立在KVC基础上的,通过KVC的动态调用机制,可以在调用之
     前或者调用之后由runtime去做一些事情。
第四部分 Obj-C/iOS的一些特性原理浅谈

OBJ-C IS C
类的数据结构
struct objc_class {
   struct objc_class* isa;          //元类,METACLASS
   struct objc_class* super_class; //指向父类指针,相当于super
   const char*       name;         //实例化的对象名字,比如 NSString* str, name是"str"
   long          version;
   unsigned long      info;
   long          instance_size; //实例大小,这个和父类的实例大小是一致的
   struct objc_ivar_list* ivars;     //类的成员变量列表
   struct objc_method_list** methodLists; //类的成员函数列表
   struct objc_protocol_list* protocols; //类需要实现的协议列表
   struct objc_cache* cache;      //这个cache用来存储经常访问到的函数或变量
};
实例,类,元类

– Obj-C,类与元类的关系:
  •   Obj-C里的元类和Python里的元类大同小异,可以支持动态创建一个类。
  •   类和元类拥有一样的数据结构,类的isa指针指向它的元类。
  •   元类的isa指针指向元类的rootclass。
  •   元类的rootclass的isa指针指向自己。


– 如何动态创建一个类:
  •   用objc_class结构体定义好类的层级关系
  •   使用objc_addClass向系统注册class
  •   使用objc_allocateClassPair动态获得Class指针
  •   用Class去实例化具体的对象
类的继承关系
函数名称(SEL)/函数指针(IMP)
[Class] 指向类的指针,Class可以理解为类的指针,指向的是类,而不是实例。
c定义:
typedef struct objc_class *Class

[id] 指向类的指针的指针,所以在实际使用的时候不需要加*号,因为本来就是一个
指针,id可以理解为指向指针的指针,因为id本身是指向类的实例的。
c定义:
typedef struct objc_object {
   struct objc_class* class_point;
} *id;

[SEL] 一个函数的标识,我们可以理解,SEL就是一个函数名,就是字符串。
c定义:
typedef char* SEL;

[IMP] 真正的函数指针,第一个参数是类的指针,第二个参数是函数标识,还有变长
参数,IMP才是真正意义上的函数指针。
c定义:
id(*IMP)(id,SEL,…)
中括号调用:Obj_MsgSend

– Oc既可以用c风格的函数调用,也可以用oc风格的中括号语法:
  • C风格的函数调用和c一样,push,push,call,ret。
  • 中括号调用则是一种间接的调用,编译器把中括号调用编译为
    Obj_MsgSend函数调用,obj_msgSend函数原型如下:



 id objc_msgSend(id self, SEL _cmd,...);
 self: isa指针,一般指向class,或者metaclass
 SEL:函数名称,就是一个函数的字符串。

   函数作用:如果self为空,返回,啥也不做;如果self不是合法isa指针
 ,core掉。查找isa的cache列表,是否有函数入口,如果没有,查询isa的方
 法列表,,是否有函数入口,如果有jmp到函数入口处。
第五部分 Obj-C/iOS 一些概念简单解析

WHY IT WORKS
iOS/Obj-C进阶


– IOS让人有些迷惑的几个概念:
  • RunLoop
  • KVC/KVO
  • Autorelease/AutoreleasePool
  • Release/Retain
  • Runtime
  • Protocal/Delegate
  • View/Model/Controller
  • Responder Chain
  • Blocks
  • Thread
RunLoop


– 结合前面的KVC机制,重新看一下runloop:
  • 简单来说,我们可以把每一次的事件触发,比如触摸屏幕,io有数据
    可读,定时器响应等都抽象成一个个具体的消息,而程序捕捉到这些
    消息后需要响应,就会执行一个个函数,oc下的函数大部分都是通过
    kv调用的,所以一个个消息我们可以抽象成一个个[id,SEL]的数据结构。
  • Runloop就可以理解为一个[id,SEL]的队列。下图可以理解为两个消息
    队列,而线程(包括主线程)在自己的for循环里不停的从队列里pop
    一个消息并执行它。

  view1           CFNetWork             view2           NSTimer
 touchUp       handleByteRecive      touchDown     actionEverySecond

    CFNetWork           UIView              NSTimer
 handleByteRecive   startAnimation     actionEverySecond
KVC/KVO


– 键值匹配,中间类:
 • Kvc:函数的调用都是kv匹配,再找到函数入口。
 • Kvo:函数在调用前会先进入一个中间类,这个中间类在编译的时候创
   建,中间类负责把监听到的值的改变消息发送给指定的对象,发送完
   毕以后在进入函数入口。
 • Ios里大量使用到kvc/kvo特性,消息通知,消息转发,键值监视等,
   可以轻松的实现订阅模式,代理模式,方便的实现线程之间的通讯,
   使得程序架构更加清晰简单。
AutoreleasePool


– AutoreleasePool自动释放池:
  • AutoreleasePool可以简单理解为一个沙箱,每次程序申请的对象,如
    果指定为autorelease,则会丢尽最近的AutoreleasePool中。
  • 结合上面的Runloop,AutoreleasePool在一个事件消息的时候创建,在
    这个消息结束的时候释放,AutoreleasePool的释放其实只是简单的对
    pool里面所有的对象做一次release操作。
  • AutoreleasePool 最好和Runloop相对应,即是说如果一个新的线程开
    辟了一个新的Runloop,那么对应的Runloop最好要拥有自己的
    AutoreleasePool,不然在和主线程共享AutoreleasePool的时候会出现
    很多数据同步问题。
AutoreleasePool生命周期
View/Controller

– View:
   • 所有的View继承于UIView,这个可以理解为用于界面显示的最基础的一个
     单元。
   • 我们可以在一个view上画东西,添加子view;view会捕捉到各种事件,比
     如,点击,移动,拖动等,也可以捕捉一些复杂的手势操作
   • 所有的view以树状关系存储,root即是程序的UIWindow。
– Controller:
   • 很容易把Controller和View搞混,其实一个Controller就是一个逻辑的集合。
   • 通常,我们把Controller作为View的代理,比如最尝使用的(
     TableView/TableViewController),table的显示,拖动,点击,都由
     tableview展现和捕捉,而tableViewController负责实现具体的代码。
   • Controller的结构关系是不确定的,一个Controller可以是多个View的代理
     ,它只是逻辑的集合体。
Responder Chain


– 消息响应链:
  • 消息响应链主要出现在交互事件上,例如手指的点击,移动等。
  • 消息响应链可以理解为一个view队列,消息会在这个队列上传递,被
    每一个view捕捉到,类似于windows下面的Message队列。最大不同的
    是windows下面的窗口有可能是属于不同的进程,而ios下所有的窗口
    属于同一个进程。
  • 每一个view在捕捉到自己的事件后(比如,自己被点击到了)可以作
    出响应,把消息在传递到下一个响应者(Responder)或者终止传递。
UIKit Responder Chain

                1.一个点击事件最初由
                当前程序(UIApplication)
                捕捉到,他通过view的
                树状关系递归遍历寻找
                当前处于最叶子节点的
                view1,发出[view1
                touchDown]消息。

                2.view1在处理完
                touchDown消息后会选
                择是否让消息继续传递
                下去,如果传递下去,
                则由responder chain上
                的第二个view响应。第
                二个view一般是在相同
                坐标上被第一个view遮
                盖住的那个view。
Thread

– C风格的线程函数:       Obj-c/iOS风格线程函数:
  void run(){       - (void)run{
      for(;;){             for(;;){
          …..                     CFRunLoopRun();
     }                      }
   }                   }



  • C线程函数是线程入口,负责驱动整个线程。
  • OC下面的线程函数其实只是开启一个runloop消息队列,这个线程只需要
    负责维护这个消息队列就可以,这个线程更像是一个worker角色,而每个
    具体的消息调用是对应的工作内容。
谢谢 Q&A




Stay hungry, Stay foolish.

Weitere ähnliche Inhalte

Was ist angesagt?

千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7Justin Lin
 
深入理解Andorid重难点
深入理解Andorid重难点深入理解Andorid重难点
深入理解Andorid重难点Bin Shao
 
Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题yiditushe
 
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJustin Lin
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closureswang hongjiang
 
Java cpu
Java cpuJava cpu
Java cpuykdsg
 
Exodus重构和向apollo迁移
Exodus重构和向apollo迁移Exodus重构和向apollo迁移
Exodus重构和向apollo迁移wang hongjiang
 
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJustin Lin
 
Shell,信号量以及java进程的退出
Shell,信号量以及java进程的退出Shell,信号量以及java进程的退出
Shell,信号量以及java进程的退出wang hongjiang
 
Ecmascript
EcmascriptEcmascript
Ecmascriptjay li
 
线程与并发
线程与并发线程与并发
线程与并发Tony Deng
 
資料永續與交換
資料永續與交換資料永續與交換
資料永續與交換Justin Lin
 
Effective linux.3.(diagnosis)
Effective linux.3.(diagnosis)Effective linux.3.(diagnosis)
Effective linux.3.(diagnosis)wang hongjiang
 
JVM内容管理和垃圾回收
JVM内容管理和垃圾回收JVM内容管理和垃圾回收
JVM内容管理和垃圾回收Tony Deng
 
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOPSpring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOPJustin Lin
 
Spring 2.0 技術手冊第六章 - Hibernate 與 Spring
Spring 2.0 技術手冊第六章 - Hibernate 與 SpringSpring 2.0 技術手冊第六章 - Hibernate 與 Spring
Spring 2.0 技術手冊第六章 - Hibernate 與 SpringJustin Lin
 
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDEJava SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDEJustin Lin
 
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2Justin Lin
 

Was ist angesagt? (20)

千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7千呼萬喚始出來的 Java SE 7
千呼萬喚始出來的 Java SE 7
 
深入理解Andorid重难点
深入理解Andorid重难点深入理解Andorid重难点
深入理解Andorid重难点
 
Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题
 
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行APIJava SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
Java SE 7 技術手冊投影片第 11 章 - 執行緒與並行API
 
Java7 fork join framework and closures
Java7 fork join framework and closuresJava7 fork join framework and closures
Java7 fork join framework and closures
 
Java cpu
Java cpuJava cpu
Java cpu
 
Exodus重构和向apollo迁移
Exodus重构和向apollo迁移Exodus重构和向apollo迁移
Exodus重构和向apollo迁移
 
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行APIJava SE 8 技術手冊第 11 章 - 執行緒與並行API
Java SE 8 技術手冊第 11 章 - 執行緒與並行API
 
Shell,信号量以及java进程的退出
Shell,信号量以及java进程的退出Shell,信号量以及java进程的退出
Shell,信号量以及java进程的退出
 
Aswan&hump
Aswan&humpAswan&hump
Aswan&hump
 
Ecmascript
EcmascriptEcmascript
Ecmascript
 
线程与并发
线程与并发线程与并发
线程与并发
 
資料永續與交換
資料永續與交換資料永續與交換
資料永續與交換
 
Effective linux.3.(diagnosis)
Effective linux.3.(diagnosis)Effective linux.3.(diagnosis)
Effective linux.3.(diagnosis)
 
JVM内容管理和垃圾回收
JVM内容管理和垃圾回收JVM内容管理和垃圾回收
JVM内容管理和垃圾回收
 
Spring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOPSpring 2.0 技術手冊第四章 - Spring AOP
Spring 2.0 技術手冊第四章 - Spring AOP
 
Spring 2.0 技術手冊第六章 - Hibernate 與 Spring
Spring 2.0 技術手冊第六章 - Hibernate 與 SpringSpring 2.0 技術手冊第六章 - Hibernate 與 Spring
Spring 2.0 技術手冊第六章 - Hibernate 與 Spring
 
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDEJava SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
 
Java Thread
Java ThreadJava Thread
Java Thread
 
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
Java SE 8 技術手冊第 14 章 - NIO 與 NIO2
 

Ähnlich wie IOS入门分享

Java程序员面试之葵花宝典
Java程序员面试之葵花宝典Java程序员面试之葵花宝典
Java程序员面试之葵花宝典yiditushe
 
[圣思园][Java SE]Io 3
[圣思园][Java SE]Io 3[圣思园][Java SE]Io 3
[圣思园][Java SE]Io 3ArBing Xie
 
lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用hugo
 
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509tidesq
 
Clojure简介与应用
Clojure简介与应用Clojure简介与应用
Clojure简介与应用Robert Hao
 
Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术bigqiang zou
 
Itpub电子杂志第四期第二稿
Itpub电子杂志第四期第二稿Itpub电子杂志第四期第二稿
Itpub电子杂志第四期第二稿yiditushe
 
12, string
12, string12, string
12, stringted-xu
 
Notes of jcip
Notes of jcipNotes of jcip
Notes of jcipDai Jun
 
掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001rainx1982
 
Java面试宝典
Java面试宝典Java面试宝典
Java面试宝典ma tao
 
模块一-Go语言特性.pdf
模块一-Go语言特性.pdf模块一-Go语言特性.pdf
模块一-Go语言特性.pdfczzz1
 
实验五 读者 写者问题
实验五 读者 写者问题实验五 读者 写者问题
实验五 读者 写者问题jason1114
 
Java并发编程培训
Java并发编程培训Java并发编程培训
Java并发编程培训dcshi
 
Java并发编程培训
Java并发编程培训Java并发编程培训
Java并发编程培训longhao
 
Javascript primer plus
Javascript primer plusJavascript primer plus
Javascript primer plusDongxu Yao
 

Ähnlich wie IOS入门分享 (20)

Java程序员面试之葵花宝典
Java程序员面试之葵花宝典Java程序员面试之葵花宝典
Java程序员面试之葵花宝典
 
[圣思园][Java SE]Io 3
[圣思园][Java SE]Io 3[圣思园][Java SE]Io 3
[圣思园][Java SE]Io 3
 
lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用lua & ngx_lua 的介绍与应用
lua & ngx_lua 的介绍与应用
 
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
Linux c++ 编程之链接与装载 -基础篇--v0.3--20120509
 
Clojure简介与应用
Clojure简介与应用Clojure简介与应用
Clojure简介与应用
 
Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术
 
Itpub电子杂志第四期第二稿
Itpub电子杂志第四期第二稿Itpub电子杂志第四期第二稿
Itpub电子杂志第四期第二稿
 
Rootkit 101
Rootkit 101Rootkit 101
Rootkit 101
 
12, string
12, string12, string
12, string
 
Notes of jcip
Notes of jcipNotes of jcip
Notes of jcip
 
掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001
 
Java面试宝典
Java面试宝典Java面试宝典
Java面试宝典
 
模块一-Go语言特性.pdf
模块一-Go语言特性.pdf模块一-Go语言特性.pdf
模块一-Go语言特性.pdf
 
Storm
StormStorm
Storm
 
实验五 读者 写者问题
实验五 读者 写者问题实验五 读者 写者问题
实验五 读者 写者问题
 
LabView with Lego NXT
LabView  with Lego NXTLabView  with Lego NXT
LabView with Lego NXT
 
Java并发编程培训
Java并发编程培训Java并发编程培训
Java并发编程培训
 
Java并发编程培训
Java并发编程培训Java并发编程培训
Java并发编程培训
 
Clojure的魅力
Clojure的魅力Clojure的魅力
Clojure的魅力
 
Javascript primer plus
Javascript primer plusJavascript primer plus
Javascript primer plus
 

IOS入门分享

  • 1. Obj-C/iOS 入门分享 搜索与算法 – 主搜索引擎技术 霜天
  • 3. 概述 • OC是c语言的超集 – OC是编译语言,不是解释语言,同时也是动态语言。 • Runtime控制了线程切换,消息队列,事件分发等。 • 类的数据结构 支持了函数动态查找,内存申请等。 • 所谓的关键字其实就是一些typedefine。甚至更简单。 – OC最牛的地方是拥有解释语言的灵活,拥有编译语言的效率。 • 拥有像java一样完善的类库。 • 拥有像python一样的元类。 • 函数调用被解释为一种类似查表的操作,简单高效。
  • 4. 文件名 – .xcodeproj • 工程文件,是个文件夹,里面定义了整个工程的文件关系。 – .pch • 预处理文件,类似于define.h之类的,定义一些公用的宏。 – .xib • 界面文件,里面定义了界面的定义,例如坐标,颜色,字体等。 – .h • 头文件。 – .m • Object-c文件,只能出现oc语法。 – .mm • 支持oc/c/c++语法,可以混编。 – .framework • 框架包,依赖包,一个文件夹,包含.h文件和.lib文件。
  • 5. 基础定义 • Obj-C特有的关键字 – Class • 类指针,和c里的class不同,这是一个类型关键字,Class class定义一 个通用的类 – Id • 对象指针,可以向像这样 id class2 = class,来指定一个指向class的指 针 – SEL • 函数名称,这个在后面会介绍c定义,SEL selector = @selector(func) 这 种定义函数的语法在Obj-C里很常见 – IMP • 这个不太常出现,这是c里面的函数指针,IMP func = [class function] , 然后就可以这样调用func()
  • 6. 基础定义 • 类 与 接口 – @interface CLASS_NAME: SUPER_CLASS_NAME <PROTOCAL>; • CLASS_NAME 定义一个类名。 • SUPER_CLASS_NAME 继承的父类 。 • PROTOCAL 实现的接口。 Interface 的感觉就像 C++里面的 Class,一般写在.h里面 – @implementation CLASS_NAME; • CLASS_NAME 的实现。 Imolementation 的感觉就是.cpp里面的实现,一般写在.m里面 – @protocal ; • 接口名称,一个类实现的接口,类似于java里面的interface。
  • 7. 基础定义 • 成员变量 与 成员函数 – @property (optional args) MEMBER_NAME • MEMBER_NAME 是成员变量名称。 • 你可以像c风格一样定义一个成员变量,也可以用property方式,这种 方式的优点就是帮你生成 getter和setter方法。 – -/+ (RETURN_TYPE)FUNCTION_NAME:arg1 COM:arg2 • -/+ 分别代表了成员函数/类函数 • 第一个参数前面是函数名称,第二个参数开始,每个参数前面是这个 参数的一些注释。 • 用参数注释起初很别扭,习惯以后,会发现这个注释很有用。 – @selector(FUNCTION_NAME) • 函数变量,可以理解为c里面的函数指针。
  • 8. 比较一个简单的实例 • #C++ #Object-C class Chinese: public People @interface Chinese:People { { public: int age ; NSInteger* _age; void eat(char* food); } } - (void)eat:(NSString* )food; @end
  • 10. 内存管理介绍 – Retain/Release/Autorelease • 一个类alloc出来以后,引用计数就为1,每次retain,引用+1 • Release既是引用-1,如果引用计数变为0,则由运行态调用类的 dealloc函数回收内存 • Autorelease是把一个类设定为自动释放类型,这种类的生存周期只有 一次完整的事件循环,超出则自动放入自动释放队列autoreleasepool 由系统自动release一遍。
  • 11. 消息管理介绍 – Runloop • 一般来说一个线程要拥有一个消息队列。 • 消息队列中存储着这个线程要分发处理的消息。 • 这些消息从何而来?一般从如下几个地方: a. 系统的点击,触摸事件。 b. 网络响应。 c. 时间阻塞的延迟响应。
  • 14. 一个main函数的入口 #import <UIKit/UIKit.h> #import "etao4iphoneAppDelegate.h" int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSLog(@"%@",NSStringFromClass([etao4iphoneAppDelegate class])); int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([etao4iphoneAppDelegate class])); [pool release]; return retVal; } 从etao4iphone里面开始,才是代码的开始。
  • 15. MVC介绍 – Model/ View/Controller • Model一般理解为数据的集合,负责获取数据,返回数据,存储数据。 • View一般理解为事件的收集与结果的展现,负责捕捉到一个事件,同 时负责把某些数据展现出来 • Controller一般理解为逻辑的集合,负责控制什么样的事件去获取什么 样的数据,并展现出来
  • 17. 代理机制介绍 – OC里广泛应用着代理机制: • 首先定义一个协议,这个协议包含了一些函数定义,但是没有实现, 类似于c++里面的纯虚类,java里面的interface接口。 • 某一个类A实现了这个代理所定义的函数。 • 某一个类B,捕捉到了一些事件,它不知道该如何处理这个事件,它 就把这个事件丢给满足协议的类A去处理。B就是A的代理。
  • 18. 代理模型介绍 感觉到了一个点击事件 类A实现了具体函数 类A 类B 实现方法: 捕捉到事件 -(void)show 协议定义了函数名 负责展现出来这个事件 协议 -(void)show
  • 19. KVC/KVO介绍 – KVC(Key-Value-Coding)/KVO(Key-Value-Observing): • OC内部所有的函数调用都被改写成obj_MsgSend函数,这个函数就是 通过给定的函数名称去查找对应的类内部的函数地址。 • KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制。 简单来说,就是一个通用指针,指针有一个成员叫isa(is a kind of), 这个指针在0x00的偏移,指向这个对象具体的类型。 • KVO是建立在KVC基础上的,通过KVC的动态调用机制,可以在调用之 前或者调用之后由runtime去做一些事情。
  • 21. 类的数据结构 struct objc_class { struct objc_class* isa; //元类,METACLASS struct objc_class* super_class; //指向父类指针,相当于super const char* name; //实例化的对象名字,比如 NSString* str, name是"str" long version; unsigned long info; long instance_size; //实例大小,这个和父类的实例大小是一致的 struct objc_ivar_list* ivars; //类的成员变量列表 struct objc_method_list** methodLists; //类的成员函数列表 struct objc_protocol_list* protocols; //类需要实现的协议列表 struct objc_cache* cache; //这个cache用来存储经常访问到的函数或变量 };
  • 22. 实例,类,元类 – Obj-C,类与元类的关系: • Obj-C里的元类和Python里的元类大同小异,可以支持动态创建一个类。 • 类和元类拥有一样的数据结构,类的isa指针指向它的元类。 • 元类的isa指针指向元类的rootclass。 • 元类的rootclass的isa指针指向自己。 – 如何动态创建一个类: • 用objc_class结构体定义好类的层级关系 • 使用objc_addClass向系统注册class • 使用objc_allocateClassPair动态获得Class指针 • 用Class去实例化具体的对象
  • 24. 函数名称(SEL)/函数指针(IMP) [Class] 指向类的指针,Class可以理解为类的指针,指向的是类,而不是实例。 c定义: typedef struct objc_class *Class [id] 指向类的指针的指针,所以在实际使用的时候不需要加*号,因为本来就是一个 指针,id可以理解为指向指针的指针,因为id本身是指向类的实例的。 c定义: typedef struct objc_object { struct objc_class* class_point; } *id; [SEL] 一个函数的标识,我们可以理解,SEL就是一个函数名,就是字符串。 c定义: typedef char* SEL; [IMP] 真正的函数指针,第一个参数是类的指针,第二个参数是函数标识,还有变长 参数,IMP才是真正意义上的函数指针。 c定义: id(*IMP)(id,SEL,…)
  • 25. 中括号调用:Obj_MsgSend – Oc既可以用c风格的函数调用,也可以用oc风格的中括号语法: • C风格的函数调用和c一样,push,push,call,ret。 • 中括号调用则是一种间接的调用,编译器把中括号调用编译为 Obj_MsgSend函数调用,obj_msgSend函数原型如下: id objc_msgSend(id self, SEL _cmd,...); self: isa指针,一般指向class,或者metaclass SEL:函数名称,就是一个函数的字符串。 函数作用:如果self为空,返回,啥也不做;如果self不是合法isa指针 ,core掉。查找isa的cache列表,是否有函数入口,如果没有,查询isa的方 法列表,,是否有函数入口,如果有jmp到函数入口处。
  • 27. iOS/Obj-C进阶 – IOS让人有些迷惑的几个概念: • RunLoop • KVC/KVO • Autorelease/AutoreleasePool • Release/Retain • Runtime • Protocal/Delegate • View/Model/Controller • Responder Chain • Blocks • Thread
  • 28. RunLoop – 结合前面的KVC机制,重新看一下runloop: • 简单来说,我们可以把每一次的事件触发,比如触摸屏幕,io有数据 可读,定时器响应等都抽象成一个个具体的消息,而程序捕捉到这些 消息后需要响应,就会执行一个个函数,oc下的函数大部分都是通过 kv调用的,所以一个个消息我们可以抽象成一个个[id,SEL]的数据结构。 • Runloop就可以理解为一个[id,SEL]的队列。下图可以理解为两个消息 队列,而线程(包括主线程)在自己的for循环里不停的从队列里pop 一个消息并执行它。 view1 CFNetWork view2 NSTimer touchUp handleByteRecive touchDown actionEverySecond CFNetWork UIView NSTimer handleByteRecive startAnimation actionEverySecond
  • 29. KVC/KVO – 键值匹配,中间类: • Kvc:函数的调用都是kv匹配,再找到函数入口。 • Kvo:函数在调用前会先进入一个中间类,这个中间类在编译的时候创 建,中间类负责把监听到的值的改变消息发送给指定的对象,发送完 毕以后在进入函数入口。 • Ios里大量使用到kvc/kvo特性,消息通知,消息转发,键值监视等, 可以轻松的实现订阅模式,代理模式,方便的实现线程之间的通讯, 使得程序架构更加清晰简单。
  • 30. AutoreleasePool – AutoreleasePool自动释放池: • AutoreleasePool可以简单理解为一个沙箱,每次程序申请的对象,如 果指定为autorelease,则会丢尽最近的AutoreleasePool中。 • 结合上面的Runloop,AutoreleasePool在一个事件消息的时候创建,在 这个消息结束的时候释放,AutoreleasePool的释放其实只是简单的对 pool里面所有的对象做一次release操作。 • AutoreleasePool 最好和Runloop相对应,即是说如果一个新的线程开 辟了一个新的Runloop,那么对应的Runloop最好要拥有自己的 AutoreleasePool,不然在和主线程共享AutoreleasePool的时候会出现 很多数据同步问题。
  • 32. View/Controller – View: • 所有的View继承于UIView,这个可以理解为用于界面显示的最基础的一个 单元。 • 我们可以在一个view上画东西,添加子view;view会捕捉到各种事件,比 如,点击,移动,拖动等,也可以捕捉一些复杂的手势操作 • 所有的view以树状关系存储,root即是程序的UIWindow。 – Controller: • 很容易把Controller和View搞混,其实一个Controller就是一个逻辑的集合。 • 通常,我们把Controller作为View的代理,比如最尝使用的( TableView/TableViewController),table的显示,拖动,点击,都由 tableview展现和捕捉,而tableViewController负责实现具体的代码。 • Controller的结构关系是不确定的,一个Controller可以是多个View的代理 ,它只是逻辑的集合体。
  • 33. Responder Chain – 消息响应链: • 消息响应链主要出现在交互事件上,例如手指的点击,移动等。 • 消息响应链可以理解为一个view队列,消息会在这个队列上传递,被 每一个view捕捉到,类似于windows下面的Message队列。最大不同的 是windows下面的窗口有可能是属于不同的进程,而ios下所有的窗口 属于同一个进程。 • 每一个view在捕捉到自己的事件后(比如,自己被点击到了)可以作 出响应,把消息在传递到下一个响应者(Responder)或者终止传递。
  • 34. UIKit Responder Chain 1.一个点击事件最初由 当前程序(UIApplication) 捕捉到,他通过view的 树状关系递归遍历寻找 当前处于最叶子节点的 view1,发出[view1 touchDown]消息。 2.view1在处理完 touchDown消息后会选 择是否让消息继续传递 下去,如果传递下去, 则由responder chain上 的第二个view响应。第 二个view一般是在相同 坐标上被第一个view遮 盖住的那个view。
  • 35. Thread – C风格的线程函数: Obj-c/iOS风格线程函数: void run(){ - (void)run{ for(;;){ for(;;){ ….. CFRunLoopRun(); } } } } • C线程函数是线程入口,负责驱动整个线程。 • OC下面的线程函数其实只是开启一个runloop消息队列,这个线程只需要 负责维护这个消息队列就可以,这个线程更像是一个worker角色,而每个 具体的消息调用是对应的工作内容。
  • 36. 谢谢 Q&A Stay hungry, Stay foolish.