精华内容
下载资源
问答
  • libev源代码分析--总体框架

    千次阅读 2014-01-14 21:21:31
    作为大树的主干,ev_run的代码是非常稳定和干净的,基本上不会掺杂外部开发者的逻辑代码进来。作为叶子的watcher,它的定位也非常明确:专注于自己的领域,只解决某一个类型的问题。不同的watcher以及watcher和主...

    先上一个例子,看看libev是怎么使用的吧。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    
    // a single header file is required
    #include <ev.h>
    
    #include <stdio.h> // for puts
    
    // every watcher type has its own typedef'd struct
    // with the name ev_TYPE
    ev_io stdin_watcher;
    ev_timer timeout_watcher;
    
    // all watcher callbacks have a similar signature
    // this callback is called when data is readable on stdin
    static void
    stdin_cb (EV_P_ ev_io *w, int revents)
    {
      puts ("stdin ready");
      // for one-shot events, one must manually stop the watcher
      // with its corresponding stop function.
      ev_io_stop (EV_A_ w);
    
      // this causes all nested ev_run's to stop iterating
      ev_break (EV_A_ EVBREAK_ALL);
    }
    
    // another callback, this time for a time-out
    static void
    timeout_cb (EV_P_ ev_timer *w, int revents)
    {
      puts ("timeout");
      // this causes the innermost ev_run to stop iterating
      ev_break (EV_A_ EVBREAK_ONE);
    }
    
    int
    main (void)
    {
      // use the default event loop unless you have special needs
      struct ev_loop *loop = EV_DEFAULT;
    
      // initialise an io watcher, then start it
      // this one will watch for stdin to become readable
      ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
      ev_io_start (loop, &stdin_watcher);
    
      // initialise a timer watcher, then start it
      // simple non-repeating 5.5 second timeout
      ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
      ev_timer_start (loop, &timeout_watcher);
    
      // now wait for events to arrive
      ev_run (loop, 0);
    
      // break was called, so exit
      return 0;
    }
    

    这是libev官网文档的例子,其中libev的使用步骤还是比较清晰的。从main开始入手,可以发现代码中主要做了这么几件事情:

    • 获取ev_loop实例。ev_loop,从名字上可以看出,它代表了一个事件循环,也是我们后面代码的主要组织者。

    • 创建和初始化watcher。libev中定义了一系列的watcher,每类watcher负责一类特定的事件。一般可以通过ev_TYPE_init函数来创建一个watcher实例(TYPE是某一种watcher类型,如:io, timer等)。例子中分别创建了io和timer两个watcher,并绑定了相应的回调函数。当感兴趣的事件发生后,对应的回调函数将会被调用。

    • 将watcher注册到ev_loop中。一般可以通过ev_TYPE_start函数来完成。注册成功后,watcher便和loop关联起来了,当loop中检测到感兴趣的事件发生,便会通知相关的watcher。

    • 启动事件循环。 即后面的ev_run函数。事件循环启动后,当前线程/进程将会被阻塞,直到循环被终止。

    在上面的例子中,在两个回调函数中的ev_break函数就是终止循环的地方。当5.5秒超时或是标准输入有输入事件,则会进入到相应的回调函数,然后会终止事件循环,退出程序。

    libev工作原理

    总的来看,libev其实是实现了Reactor模式。当中主要包含了这么几个角色:watcher, ev_loop和ev_run。

    watcher

    watcher是Reactor中的Event Handler。一方面,它向事件循环提供了统一的调用接口(按类型区分);另一方面,它是外部代码的注入口,维护着具体的watcher信息,如:绑定的回调函数,watcher的优先级,是否激活等。

    在ev.h中我们可以看到各种watcher的定义,如:ev_io, ev_timer等。其中,watcher的公共属性定义如下:

    1
    2
    3
    4
    5
    6
    7
    
    /* shared by all watchers */
    #define EV_WATCHER(type)         \
     int active; /* private */           \
     int pending; /* private */          \
     EV_DECL_PRIORITY /* private  int priority; */       \
     EV_COMMON /* rw  void *data; */             \
     EV_CB_DECLARE (type) /* private */
    

    其中的宏定义如下:

    1
    2
    3
    
    # define EV_DECL_PRIORITY int priority;
    # define EV_COMMON void *data;
    # define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
    
    • active: 表示当前watcher是否被激活。ev_TYPE_start调用后置位,ev_TYPE_stop调用后复位;

    • pending: 表示当前watcher有事件就绪,等待处理。pending的值其实就是当前watcher在pendings队列中的下标;

    • priority: 是当前watcher的优先级;

    • data: 附加数据指针,用来在watcher中携带额外所需的数据;

    • cb:是事件触发后的回调函数定义。

    具体的watcher再在此基础上添加额外的属性。开发者可以根据需要,选择特定类型的watcher,创建实例并进行初始化,然后将实例注册到loop中即可。libev中定义了若干种类型的watcher,每类watcher负责解决某一特定领域的问题(如:io, timer, signal等),可以在ev.h中看到这些watcher的定义。

    ev_loop

    ev_loop则是一个Reactor的角色,是事件循环的上下文环境,就像一根竹签,把前面的watcher实例像糖葫芦一样串起来。

    ev_loop的定义

    ev_loop的定义在ev.c中,具体如下:

    1
    2
    3
    4
    5
    6
    7
    8
    
    struct ev_loop
    {
      ev_tstamp ev_rt_now;
      #define ev_rt_now ((loop)->ev_rt_now)
      #define VAR(name,decl) decl;
          #include "ev_vars.h"
      #undef VAR
    };
    

    ev_vars.h中定义了ev_loop的各种属性。在ev_wrap.h中则定义了与loop相关的各种宏,代码中大多都是以宏的形式进行操作。

    watcher的管理

    在ev_loop中,watcher按各自的类型进行分类存储。如:io的loop->anfds,timer的loop->timers。ev_TYPE_start在激活watcher后,便将它加入到相应的存储结构中(具体的实现在后面介绍watcher的文章再分析)。

    在事件循环中,有事件就绪的watcher会被挑拣出来,保存到ev_loop中。这些就绪的watcher主要由loop->pendings和loop->pendingcnt来维护(如下图所示)。这两个东西都是二维数组,第一维都是优先级。pendings中存的是ANPENDING实例,后者的做要作用就是维护就绪的watcher指针; 而pendingcnt中存的则是对应优先级上的pendings元素的数量。在每个就绪的watcher上也会有一个pending字段记录它在pendings列表中的下标,这样就可以通过watcher很方便的找到它在pendings列表中的位置了,这对删除操作很有帮助。

    在一轮事件循环结束后,则会根据优先级,依次触发就绪的watcher。

    pendings结构图

    bool ev_run(loop, flag)

    ev_run函数是执行事件循环的引擎,即Reactor模式中的select方法。通过向ev_run函数传递一个ev_loop实例,便可以开启一个事件循环。ev_run实际上是一个巨大的do-while循环,期间会检查loop中注册的各种watcher的事件。如果有事件就绪,则触发相应的watcher。这个循环会一直持续到ev_break被调用或者无active的watcher为止。当然,也可以通过传递EVRUN_NOWAIT或EVRUN_ONCE等flag来控制循环的阻塞行为。

    ev_run的工作内容,在官方文档的API中有详细说明,通过文档有助于对ev_run的理解。具体的代码有点长,在这里就不贴了,感兴趣的同学可以在ev.c中查看ev_run的实现代码。剔除掉条件检查和一些无关紧要的代码,主要的流程如下图所示。

    ev_run流程图

    可以看到,ev_run的主要工作就是按watcher的分类,先后检查各种类型的watcher上的事件,通过ev_feed_event函数将就绪的watcher加入到pending的数据结构中。最后调用ev_invoke_pending,触发pending中的watcher。完了以后会检查,是否还有active的watcher以及是否有ev_break调用过,然后决定是否要继续下一轮循环。

    总结

    总的来看,libev的结构设计还是非常清晰。如果说,主循环ev_run是libev这棵大树的主干,那么功能强大,数量繁多的watcher就是这棵大树的树叶,而循环上下文ev_loop则是连接主干和树叶的树枝,它们的分工与职责是相当明确的。作为大树的主干,ev_run的代码是非常稳定和干净的,基本上不会掺杂外部开发者的逻辑代码进来。作为叶子的watcher,它的定位也非常明确:专注于自己的领域,只解决某一个类型的问题。不同的watcher以及watcher和主循环之间并没有太多的干扰和耦合,这也是libev能如此灵活扩展的原因。而中间的树枝ev_loop的作用也是不言而喻的,正是因为它在中间的调和,前面两位哥们才能活得这么有个性。

    看到这里,libev的主体架构已经比较清楚了,但是似乎还没看到与性能相关的关键代码。与主干代码不一样,这些代码更多的是隐藏在实现具体逻辑的地方,也就是watcher之中的。虽然watcher的使用接口都比较相似,但是不同的watcher,底层的数据结构和处理策略还是不一样的。下面一篇文章我们就来探索一下libev中比较常用的几种watcher的设计与实现。

    展开全文
  • H.265/HEVC码率控制总体框架代码解读(上)

    千次阅读 热门讨论 2017-09-27 15:30:31
    Control)部分是我研究生期间的研究重点,近期在导师的敦促下开始论文写作,需要总结整个码率控制的框架以及自身对码率控制的算法改进部分,借此机会把码率控制的理论部分与实际代码部分进行一个整理和归纳,可作为...

    HEVC的码率控制(Rate Control)部分是我研究生期间的研究重点,近期在导师的敦促下开始论文写作,需要总结整个码率控制的框架以及自身对码率控制的算法改进部分,借此机会把码率控制的理论部分与实际代码部分进行一个整理和归纳,可作为各位博友的参考,如有错误,敬请指正!(参考软件版本:https://hevc.hhi.fraunhofer.de/svn/svn_HEVCSoftware/tags/HM-16.15/ )

    上:介绍码率控制的初始化部分
    首先码率控制的作用是在有限的带宽下尽可能地提高整体视频的性能,并保证比特分配的准确性,其中HEVC中的带宽用比特率(Bitrate)来表示。了解码率控制应从一份提案入手,即JCTVC-K0103 http://phenix.it-sudparis.eu/jct/,这篇文章奠定了码率控制的整体框架。之后的JCTVC-M0036、JCTVC-M0257在JCTVC-K0103的基础上进行扩展和改进,但总体的框架不变。码率控制的整体流程大致如下。
    1. 对码率控制进行初始化。(主要分为序列级别,GOP级别,frame级别,LCU级别)
    2. 对上述4个级别分别进行比特的分配。
    3. 将各个单元分配的比特数根据R-lambda和lambda-QP模型求出各个单元的最佳QP,并应用于编码中。
    接下来就对这三个部分进行解读,并加入一些我自己对各个模块的理解。

    1.初始化部分

    1.1.在函数TEncTop::create () 中,若m_RCEnableRateControl开启,即cfg文件中的RateCtrl==1,对整个码率控制模块进行初始化。
    //初始化函数m_cRateCtrl.init()主要根据序列参数进行初始化,包括Int totalFrames, Int targetBitrate, Int frameRate, Int GOPSize, Int picWidth, Int picHeight, Int LCUWidth, Int LCUHeight, Int keepHierBits, Bool useLCUSeparateModel, GOPEntry  GOPList[MAX_GOP]这里主要解释以下形参中的keepHierBits,即是否采用分层编码,若采用,则各帧的比特分配是不一样的,否则,各帧的比特分配权重相同,在之后的代码中进行详解。
    if ( m_RCEnableRateControl )
    {
    m_cRateCtrl.init( m_framesToBeEncoded, m_RCTargetBitrate, (Int)( (Double)m_iFrameRate/m_temporalSubsampleRatio + 0.5), m_iGOPSize, m_iSourceWidth, m_iSourceHeight,
    m_maxCUWidth, m_maxCUHeight,m_RCKeepHierarchicalBit, m_RCUseLCUSeparateModel, m_GOPList );
    }
    转到m_cRateCtrl.init()的定义之中,这里删除了部分else语句以提升代码的阅读性。
    Void TEncRateCtrl::init( Int totalFrames, Int targetBitrate, Int frameRate, Int GOPSize, Int picWidth, Int picHeight, Int LCUWidth, Int LCUHeight, Int keepHierBits, Bool useLCUSeparateModel, GOPEntry  GOPList[MAX_GOP] )
    {
      destroy();
      Bool isLowdelay = true;  //判断编码方式是否是Lowdelay
      for ( Int i=0; i<GOPSize-1; i++ )
      {
        if ( GOPList[i].m_POC > GOPList[i+1].m_POC )
        {
          isLowdelay = false;
          break;
        }
      }
      Int numberOfLevel = 1;
      Int adaptiveBit = 0;
      if ( keepHierBits > 0 )
      {
        numberOfLevel = Int( log((Double)GOPSize)/log(2.0) + 0.5 ) + 1;
      }
      if ( !isLowdelay && GOPSize == 8 )
      {
        numberOfLevel = Int( log((Double)GOPSize)/log(2.0) + 0.5 ) + 1;
      }
      numberOfLevel++;    // intra picture
      numberOfLevel++;    // non-reference picture
      Int* bitsRatio;
      bitsRatio = new Int[ GOPSize ]; //初始化每一帧权重
      for ( Int i=0; i<GOPSize; i++ )
      {
        bitsRatio[i] = 10;
        if ( !GOPList[i].m_refPic )
        {
          bitsRatio[i] = 2;
        }
      }
      if ( keepHierBits > 0 )  //如果采用分层编码,则每一帧的权重不同,这里的权重即为每一帧获得比特数的比例
      {
        Double bpp = (Double)( targetBitrate / (Double)( frameRate*picWidth*picHeight ) );   //判断当前带宽(Bitrate)分配到每一帧的每一个像素点上的比特数,即bit per pixel,根据bpp调整权重策略
        if ( GOPSize == 4 && isLowdelay )    //Lowdelay下每一帧权重
        {
          if ( bpp > 0.2 )
          {
            bitsRatio[0] = 2;
            bitsRatio[1] = 3;
            bitsRatio[2] = 2;
            bitsRatio[3] = 6;
          }
          else if( bpp > 0.1 )
          {
            bitsRatio[0] = 2;
            bitsRatio[1] = 3;
            bitsRatio[2] = 2;
            bitsRatio[3] = 10;
          }
          if ( keepHierBits == 2 )
          {
            adaptiveBit = 1;
          }
        }
        else if ( GOPSize == 8 && !isLowdelay )     //Random Access下每一帧权重
        {
          if ( bpp > 0.2 )
          {
            bitsRatio[0] = 15;
            bitsRatio[1] = 5;
            bitsRatio[2] = 4;
            bitsRatio[3] = 1;
            bitsRatio[4] = 1;
            bitsRatio[5] = 4;
            bitsRatio[6] = 1;
            bitsRatio[7] = 1;
          }
          else if ( bpp > 0.1 )
          {
            bitsRatio[0] = 20;
            bitsRatio[1] = 6;
            bitsRatio[2] = 4;
            bitsRatio[3] = 1;
            bitsRatio[4] = 1;
            bitsRatio[5] = 4;
            bitsRatio[6] = 1;
            bitsRatio[7] = 1;
          }
    
          if ( keepHierBits == 2 )
          {
            adaptiveBit = 2;
          }
        }
        else
        {
          printf( "\n hierarchical bit allocation is not support for the specified coding structure currently.\n" );
        }
      }
      Int* GOPID2Level = new Int[ GOPSize ];
      for ( Int i=0; i<GOPSize; i++ )
      {
        GOPID2Level[i] = 1;
        if ( !GOPList[i].m_refPic )
        {
          GOPID2Level[i] = 2;
        }
      }
      if ( keepHierBits > 0 )  //这里要说明一下GOPID2Level,在这块代码块之后附上图文解释。
      {
        if ( GOPSize == 4 && isLowdelay )
        {
          GOPID2Level[0] = 3;
          GOPID2Level[1] = 2;
          GOPID2Level[2] = 3;
          GOPID2Level[3] = 1;
        }
      }
      if ( !isLowdelay && GOPSize == 8 )
      {
        GOPID2Level[0] = 1;
        GOPID2Level[1] = 2;
        GOPID2Level[2] = 3;
        GOPID2Level[3] = 4;
        GOPID2Level[4] = 4;
        GOPID2Level[5] = 3;
        GOPID2Level[6] = 4;
        GOPID2Level[7] = 4;
      }
      m_encRCSeq = new TEncRCSeq;     //将计算后得到的各项数据传入码率控制的初始化函数(TEncRateCtrl.cpp)之中
      m_encRCSeq->create( totalFrames, targetBitrate, frameRate, GOPSize, picWidth, picHeight, LCUWidth, LCUHeight, numberOfLevel, useLCUSeparateModel, adaptiveBit );
      m_encRCSeq->initBitsRatio( bitsRatio );
      m_encRCSeq->initGOPID2Level( GOPID2Level );
      m_encRCSeq->initPicPara();
      if ( useLCUSeparateModel )
      {
        m_encRCSeq->initLCUPara();
      }
      m_CpbSaturationEnabled = false;
      m_cpbSize              = targetBitrate;
      m_cpbState             = (UInt)(m_cpbSize*0.5f);
      m_bufferingRate        = (Int)(targetBitrate / frameRate);
      delete[] bitsRatio;      //销毁
      delete[] GOPID2Level;
    }

    PS:用下图解释以下GOPID2Level的概念,这是一个Random Access的示例图(图有点丑,见谅。。。),图中的1~8表示一个GOP中的8帧,在I帧(0)编码完成之后,首先进行编码的是第8帧,之后0和8共同作为第4帧的参考帧,再由0和4共同决定2、0和2共同决定1的编码。这样就仿佛是一个层次结构,一层一层进行编码,也就有了layer这个标识符以标志各帧所属的层。而GOPID2Level 也就是所谓的layer,其中GOPID2Level[0]代表第8帧,GOPID2Level[1]代表第4帧,GOPID2Level[2]代表第2帧,GOPID2Level[3]代表第1和第3帧,以此类推。

                        

    1.2.在TEncTop::encode() 中,对GOP级别内容进行初始化,主要内容是对一个GOP中的各帧进行计算。

    if ( m_RCEnableRateControl )
    {
    m_cRateCtrl.initRCGOP( m_iNumPicRcvd );
    }

    initRCGOP(  )函数只有两行代码,最重要的就是 m_encRCGOP->create( m_encRCSeq, numberOfPictures ),如下
    Void TEncRCGOP::create( TEncRCSeq* encRCSeq, Int numPic )
    {
      destroy();
      Int targetBits = xEstGOPTargetBits( encRCSeq, numPic );     //计算每个GOP分配的比特数
      if ( encRCSeq->getAdaptiveBits() > 0 && encRCSeq->getLastLambda() > 0.1 )//一般不进入此if判断,除非开启adaptiveBits
      {
        Double targetBpp = (Double)targetBits / encRCSeq->getNumPixel();
        Double basicLambda = 0.0;
        Double* lambdaRatio = new Double[encRCSeq->getGOPSize()];
        Double* equaCoeffA = new Double[encRCSeq->getGOPSize()];
        Double* equaCoeffB = new Double[encRCSeq->getGOPSize()];
        if ( encRCSeq->getAdaptiveBits() == 1 )   // for GOP size =4, low delay case
        {
          if ( encRCSeq->getLastLambda() < 120.0 )
          {
            lambdaRatio[1] = 0.725 * log( encRCSeq->getLastLambda() ) + 0.5793;
            lambdaRatio[0] = 1.3 * lambdaRatio[1];
            lambdaRatio[2] = 1.3 * lambdaRatio[1];
            lambdaRatio[3] = 1.0;
          }
          else
          {
            lambdaRatio[0] = 5.0;
            lambdaRatio[1] = 4.0;
            lambdaRatio[2] = 5.0;
            lambdaRatio[3] = 1.0;
          }
        }
        else if ( encRCSeq->getAdaptiveBits() == 2 )  // for GOP size = 8, random access case
        {
          if ( encRCSeq->getLastLambda() < 90.0 )
          {
            lambdaRatio[0] = 1.0;
            lambdaRatio[1] = 0.725 * log( encRCSeq->getLastLambda() ) + 0.7963;
            lambdaRatio[2] = 1.3 * lambdaRatio[1];
            lambdaRatio[3] = 3.25 * lambdaRatio[1];
            lambdaRatio[4] = 3.25 * lambdaRatio[1];
            lambdaRatio[5] = 1.3  * lambdaRatio[1];
            lambdaRatio[6] = 3.25 * lambdaRatio[1];
            lambdaRatio[7] = 3.25 * lambdaRatio[1];
          }
          else
          {
            lambdaRatio[0] = 1.0;
            lambdaRatio[1] = 4.0;
            lambdaRatio[2] = 5.0;
            lambdaRatio[3] = 12.3;
            lambdaRatio[4] = 12.3;
            lambdaRatio[5] = 5.0;
            lambdaRatio[6] = 12.3;
            lambdaRatio[7] = 12.3;
          }
        }
        xCalEquaCoeff( encRCSeq, lambdaRatio, equaCoeffA, equaCoeffB, encRCSeq->getGOPSize() );
        basicLambda = xSolveEqua( targetBpp, equaCoeffA, equaCoeffB, encRCSeq->getGOPSize() );
        encRCSeq->setAllBitRatio( basicLambda, equaCoeffA, equaCoeffB );
        delete []lambdaRatio;
        delete []equaCoeffA;
        delete []equaCoeffB;
      }
      m_picTargetBitInGOP = new Int[numPic];
      Int i;
      Int totalPicRatio = 0;
      Int currPicRatio = 0;
      for ( i=0; i<numPic; i++ )      //统计每一帧的权重之和,在1.1中已定义
      {
        totalPicRatio += encRCSeq->getBitRatio( i );
      }
      for ( i=0; i<numPic; i++ )
      {
        currPicRatio = encRCSeq->getBitRatio( i );
        m_picTargetBitInGOP[i] = (Int)( ((Double)targetBits) * currPicRatio / totalPicRatio );     //运用每一帧的权重分配对应比特数
      }
      m_encRCSeq    = encRCSeq;
      m_numPic       = numPic;
      m_targetBits   = targetBits;
      m_picLeft      = m_numPic;
      m_bitsLeft     = m_targetBits;
    }

    1.3.在TEncGOP::compressGOP()中,对frame进行初始化


        if ( m_pcCfg->getUseRateCtrl() ) // TODO: does this work with multiple slices and slice-segments?
        {
          Int frameLevel = m_pcRateCtrl->getRCSeq()->getGOPID2Level( iGOPid );
          if ( pcPic->getSlice(0)->getSliceType() == I_SLICE )
          {
            frameLevel = 0;
          }
          m_pcRateCtrl->initRCPic( frameLevel );    //对frame层级进行初始化


    进入m_pcRateCtrl->initRCPic()函数,在里面的m_encRCPic->create()函数中可以看到对frame中参数的定义,包括各项基本信息,如下。(这一块不难,参照对应变量即可了解其含义)
    Void TEncRCPic::create( TEncRCSeq* encRCSeq, TEncRCGOP* encRCGOP, Int frameLevel, list<TEncRCPic*>& listPreviousPictures )
    {
      destroy();
      m_encRCSeq = encRCSeq;
      m_encRCGOP = encRCGOP;
      Int targetBits    = xEstPicTargetBits( encRCSeq, encRCGOP );
      Int estHeaderBits = xEstPicHeaderBits( listPreviousPictures, frameLevel );
      if ( targetBits < estHeaderBits + 100 )
      {
        targetBits = estHeaderBits + 100;   // at least allocate 100 bits for picture data
      }
      m_frameLevel       = frameLevel;//基础信息
      m_numberOfPixel    = encRCSeq->getNumPixel();
      m_numberOfLCU      = encRCSeq->getNumberOfLCU();
      m_estPicLambda     = 100.0;
      m_targetBits       = targetBits;
      m_estHeaderBits    = estHeaderBits;
      m_bitsLeft         = m_targetBits;
      Int picWidth       = encRCSeq->getPicWidth();
      Int picHeight      = encRCSeq->getPicHeight();
      Int LCUWidth       = encRCSeq->getLCUWidth();
      Int LCUHeight      = encRCSeq->getLCUHeight();
      Int picWidthInLCU  = ( picWidth  % LCUWidth  ) == 0 ? picWidth  / LCUWidth  : picWidth  / LCUWidth  + 1;
      Int picHeightInLCU = ( picHeight % LCUHeight ) == 0 ? picHeight / LCUHeight : picHeight / LCUHeight + 1;
      m_lowerBound       = xEstPicLowerBound( encRCSeq, encRCGOP );
      m_LCULeft         = m_numberOfLCU;
      m_bitsLeft       -= m_estHeaderBits;
      m_pixelsLeft      = m_numberOfPixel;
      m_LCUs           = new TRCLCU[m_numberOfLCU];
      Int i, j;
      Int LCUIdx;
      for ( i=0; i<picWidthInLCU; i++ )      //每个LCU的参数进行初始化
      {
        for ( j=0; j<picHeightInLCU; j++ )
        {
          LCUIdx = j*picWidthInLCU + i;
          m_LCUs[LCUIdx].m_actualBits = 0;
          m_LCUs[LCUIdx].m_QP         = 0;
          m_LCUs[LCUIdx].m_lambda     = 0.0;
          m_LCUs[LCUIdx].m_targetBits = 0;
          m_LCUs[LCUIdx].m_bitWeight  = 1.0;
          Int currWidth  = ( (i == picWidthInLCU -1) ? picWidth  - LCUWidth *(picWidthInLCU -1) : LCUWidth  );
          Int currHeight = ( (j == picHeightInLCU-1) ? picHeight - LCUHeight*(picHeightInLCU-1) : LCUHeight );
          m_LCUs[LCUIdx].m_numberOfPixel = currWidth * currHeight;
        }
      }
      m_picActualHeaderBits = 0;
      m_picActualBits       = 0;
      m_picQP               = 0;
      m_picLambda           = 0.0;
    }

    1.4.在TEncSlice::compressSlice()中,对LCU进行初始化,主要是bpp,lambda,QP这几个参数
     if ( m_pcCfg->getUseRateCtrl() )
          Int estQP        = pcSlice->getSliceQp();
          Double estLambda = -1.0;
          Double bpp       = -1.0;
    以上部分就是所有RC中初始化参数的设定。

    展开全文
  •  随着机器人领域的快速发展和复杂化,代码的复用性和模块化的需求原来越强烈,而已有的开源机器人系统又不能很好的适应需求。2010年Willow Garage公司发布了开源机器人操作系统ROS(robot operating system),很快...

    ROS探索总结(一)——ROS简介


    一、历史

           随着机器人领域的快速发展和复杂化,代码的复用性和模块化的需求原来越强烈,而已有的开源机器人系统又不能很好的适应需求。2010年Willow Garage公司发布了开源机器人操作系统ROS(robot operating system),很快在机器人研究领域展开了学习和使用ROS的热潮。


           ROS系统是起源于2007年斯坦福大学人工智能实验室的项目与机器人技术公司Willow Garage的个人机器人项目(Personal Robots Program)之间的合作,2008年之后就由Willow Garage来进行推动。已经有四年多的时间了 (视频)。随着PR2那些不可思议的表现,譬如叠衣服,插插座,做早饭,ROS也得到越来越多的关注。Willow Garage公司也表示希望借助开源的力量使PR2变成“全能”机器人。

           PR2价格高昂,2011年零售价高达40万美元。PR2现主要用于研究。PR2有两条手臂,每条手臂七个关节,手臂末端是一个可以张合的钳子。PR2依靠底部的四个轮子移动。在PR2的头部,胸部,肘部,钳子上安装有高分辨率摄像头,激光测距仪,惯性测量单元,触觉传感器等丰富的传感设备。在PR2的底部有两台8核的电脑作为机器人各硬件的控制和通讯中枢。两台电脑安装有Ubuntu和ROS。


    二、设计目标

           ROS是开源的,是用于机器人的一种后操作系统,或者说次级操作系统。它提供类似操作系统所提供的功能,包含硬件抽象描述、底层驱动程序管理、共用功能的执行、程序间的消息传递、程序发行包管理,它也提供一些工具程序和库用于获取、建立、编写和运行多机整合的程序。

           

           ROS的首要设计目标是在机器人研发领域提高代码复用率。ROS是一种分布式处理框架(又名Nodes)。这使可执行文件能被单独设计,并且在运行时松散耦合。这些过程可以封装到数据包(Packages)和堆栈(Stacks)中,以便于共享和分发。ROS还支持代码库的联合系统。使得协作亦能被分发。这种从文件系统级别到社区一级的设计让独立地决定发展和实施工作成为可能。上述所有功能都能由ROS的基础工具实现。


    三、主要特点

           ROS的运行架构是一种使用ROS通信模块实现模块间P2P的松耦合的网络连接的处理架构,它执行若干种类型的通讯,包括基于服务的同步RPC(远程过程调用)通讯、基于Topic的异步数据流通讯,还有参数服务器上的数据存储。但是ROS本身并没有实时性。

           ROS的主要特点可以归纳为以下几条:

         (1)点对点设计


           一个使用ROS的系统包括一系列进程,这些进程存在于多个不同的主机并且在运行过程中通过端对端的拓扑结构进行联系。虽然基于中心服务器的那些软件框架也可以实现多进程和多主机的优势,但是在这些框架中,当各电脑通过不同的网络进行连接时,中心数据服务器就会发生问题。
          ROS的点对点设计以及服务和节点管理器等机制可以分散由计算机视觉和语音识别等功能带来的实时计算压力,能够适应多机器人遇到的挑战。

           (2)多语言支持

           在写代码的时候,许多编程者会比较偏向某一些编程语言。这些偏好是个人在每种语言的编程时间、调试效果、语法、执行效率以及各种技术和文化的原因导致的结果。为了解决这些问题,我们将ROS设计成了语言中立性的框架结构。ROS现在支持许多种不同的语言,例如C++、Python、Octave和LISP,也包含其他语言的多种接口实现。


           ROS的特殊性主要体现在消息通讯层,而不是更深的层次。端对端的连接和配置利用XML-RPC机制进行实现,XML-RPC也包含了大多数主要语言的合理实现描述。我们希望ROS能够利用各种语言实现的更加自然,更符合各种语言的语法约定,而不是基于C语言给各种其他语言提供实现接口。然而,在某些情况下利用已经存在的库封装后支持更多新的语言是很方便的,比如Octave的客户端就是通过C++的封装库进行实现的。
           为了支持交叉语言,ROS利用了简单的、语言无关的接口定义语言去描述模块之间的消息传送。接口定义语言使用了简短的文本去描述每条消息的结构,也允许消息的合成,例如下图就是利用接口定义语言描述的一个点的消息:


           每种语言的代码产生器就会产生类似本种语言目标文件,在消息传递和接收的过程中通过ROS自动连续并行的实现。这就节省了重要的编程时间,也避免了错误:之前3行的接口定义文件自动的扩展成137行的C++代码,96行的Python代码,81行的Lisp代码和99行的Octave代码。因为消息是从各种简单的文本文件中自动生成的,所以很容易列举出新的消息类型。在编写的时候,已知的基于ROS的代码库包含超过四百种消息类型,这些消息从传感器传送数据,使得物体检测到了周围的环境。
           最后的结果就是一种语言无关的消息处理,让多种语言可以自由的混合和匹配使用。

           (3)精简与集成

           大多数已经存在的机器人软件工程都包含了可以在工程外重复使用的驱动和算法,不幸的是,由于多方面的原因,大部分代码的中间层都过于混乱,以至于很困难提取出它的功能,也很难把它们从原型中提取出来应用到其他方面。
          为了应对这种趋势,我们鼓励将所有的驱动和算法逐渐发展成为和ROS没有依赖性单独的库。ROS建立的系统具有模块化的特点,各模块中的代码可以单独编译,而且编译使用的CMake工具使它很容易的就实现精简的理念。ROS基本将复杂的代码封装在库里,只是创建了一些小的应用程序为ROS显示库的功能,就允许了对简单的代码超越原型进行移植和重新使用。作为一种新加入的有优势,单元测试当代码在库中分散后也变得非常的容易,一个单独的测试程序可以测试库中很多的特点。
           ROS利用了很多现在已经存在的开源项目的代码,比如说从Player项目中借鉴了驱动、运动控制和仿真方面的代码,从OpenCV中借鉴了视觉算法方面的代码,从OpenRAVE借鉴了规划算法的内容,还有很多其他的项目。在每一个实例中,ROS都用来显示多种多样的配置选项以及和各软件之间进行数据通信,也同时对它们进行微小的包装和改动。ROS可以不断的从社区维护中进行升级,包括从其他的软件库、应用补丁中升级ROS的源代码。

           (4)工具包丰富

           为了管理复杂的ROS软件框架,我们利用了大量的小工具去编译和运行多种多样的ROS组建,从而设计成了内核,而不是构建一个庞大的开发和运行环境。
           这些工具担任了各种各样的任务,例如,组织源代码的结构,获取和设置配置参数,形象化端对端的拓扑连接,测量频带使用宽度,生动的描绘信息数据,自动生成文档等等。尽管我们已经测试通过像全局时钟和控制器模块的记录器的核心服务,但是我们还是希望能把所有的代码模块化。我们相信在效率上的损失远远是稳定性和管理的复杂性上无法弥补的。

           (5)免费并且开源

          ROS所有的源代码都是公开发布的。我们相信这将必定促进ROS软件各层次的调试,不断的改正错误。虽然像Microsoft Robotics Studio和Webots这样的非开源软件也有很多值得赞美的属性,但是我们认为一个开源的平台也是无可为替代的。当硬件和各层次的软件同时设计和调试的时候这一点是尤其真实的。
          ROS以分布式的关系遵循这BSD许可,也就是说允许各种商业和非商业的工程进行开发。ROS通过内部处理的通讯系统进行数据的传递,不要求各模块在同样的可执行功能上连接在一起。如此,利用ROS构建的系统可以很好的使用他们丰富的组件:个别的模块可以包含被各种协议保护的软件,这些协议从GPL到BSD,但是许可的一些“污染物”将在模块的分解上就完全消灭掉。

    参考资料:
    (1)《开源机器人操作系统——ROS》 张建伟等著
    (2)《an open-source Robot Operating System》 paper
    (3)  willowgarage公司网站:http://www.willowgarage.com/
    (4)  ROS官方wiki:http://www.ros.org

    ----------------------------------------------------------------






    ROS探索总结(二)——ROS总体框架


    一、  总体结构

           根据ROS系统代码的维护者和分布来标示,主要有两大部分:
         (1)main:核心部分,主要由Willow Garage公司和一些开发者设计、提供以及维护。它提供了一些分布式计算的基本工具,以及整个ROS的核心部分的程序编写。
         (2)universe:全球范围的代码,有不同国家的ROS社区组织开发和维护。一种是库的代码,如OpenCV、PCL等;库的上一层是从功能角度提供的代码,如人脸识别,他们调用下层的库;最上层的代码是应用级的代码,让机器人完成某一确定的功能。
           一般是从另一个角度对ROS分级的,主要分为三个级别:计算图级、文件系统级、社区级。

    二、  计算图级

           计算图是ROS处理数据的一种点对点的网络形式。程序运行时,所有进程以及他们所进行的数据处理,将会通过一种点对点的网络形式表现出来。这一级主要包括几个重要概念:节点(node)、消息(message)、主题(topic)、服务(service)。

           (1)  节点

           节点就是一些直行运算任务的进程。ROS利用规模可增长的方式是代码模块化:一个系统就是典型的由很多节点组成的。在这里,节点也可以被称之为“软件模块”。我们使用“节点”使得基于ROS的系统在运行的时候更加形象化:当许多节点同时运行时,可以很方便的将端对端的通讯绘制成一个图表,在这个图表中,进程就是图中的节点,而端对端的连接关系就是其中弧线连接。

           (2)  消息

           节点之间是通过传送消息进行通讯的。每一个消息都是一个严格的数据结构。原来标准的数据类型(整型,浮点型,布尔型等等)都是支持的,同时也支持原始数组类型。消息可以包含任意的嵌套结构和数组(很类似于C语言的结构structs)。

           (3)  主题


           消息以一种发布/订阅的方式传递。一个节点可以在一个给定的主题中发布消息。一个节点针对某个主题关注与订阅特定类型的数据。可能同时有多个节点发布或者订阅同一个主题的消息。总体上,发布者和订阅者不了解彼此的存在。

           (4)  服务

            虽然基于话题的发布/订阅模型是很灵活的通讯模式,但是它广播式的路径规划对于可以简化节点设计的同步传输模式并不适合。在ROS中,我们称之为一个服务,用一个字符串和一对严格规范的消息定义:一个用于请求,一个用于回应。这类似于web服务器,web服务器是由URIs定义的,同时带有完整定义类型的请求和回复文档。需要注意的是,不像话题,只有一个节点可以以任意独有的名字广播一个服务:只有一个服务可以称之为“分类象征”,比如说,任意一个给出的URI地址只能有一个web服务器。
            在上面概念的基础上,需要有一个控制器可以使所有节点有条不紊的执行,这就是一个ROS的控制器(ROS Master)。
            ROS Master 通过RPC(Remote Procedure Call Protocol,远程过程调用)提供了登记列表和对其他计算图表的查找。没有控制器,节点将无法找到其他节点,交换消息或调用服务。
            比如控制节点订阅和发布消息的模型如下:

            ROS的控制器给ROS的节点存储了主题和服务的注册信息。节点与控制器通信从而报告它们的注册信息。当这些节点与控制器通信的时候,它们可以接收关于其他以注册及节点的信息并且建立与其它以注册节点之间的联系。当这些注册信息改变时控制器也会回馈这些节点,同时允许节点动态创建与新节点之间的连接。
            节点与节点之间的连接是直接的,控制器仅仅提供了查询信息,就像一个DNS服务器。节点订阅一个主题将会要求建立一个与出版该主题的节点的连接,并且将会在同意连接协议的基础上建立该连接。
             另:ROS控制器控制服务:


    三、  文件系统级

            ROS文件系统级指的是在硬盘上面查看的ROS源代码的组织形式。

            ROS中有无数的节点、消息、服务、工具和库文件,需要有效的结构去管理这些代码。在ROS的文件系统级,有以下几个重要概念:包(package)、堆(stack)、

            (1)  包


            ROS的软件以包的方式组织起来。包包含节点、ROS依赖库、数据套、配置文件、第三方软件、或者任何其他逻辑构成。包的目标是提供一种易于使用的结构以便于软件的重复使用。总得来说,ROS的包短小精干。

            (2)  堆


            堆是包的集合,它提供一个完整的功能,像“navigation stack”。Stack与版本号关联,同时也是如何发行ROS软件方式的关键。
            ROS是一种分布式处理框架。这使可执行文件能被单独设计,并且在运行时松散耦合。这些过程可以封装到包(Packages)和堆(Stacks)中,以便于共享和分发。下图是在包和堆在文件中的具体结构:
             Manifests (manifest.xml):提供关于Package元数据,包括它的许可信息和Package之间依赖关系,以及语言特性信息像编译旗帜(编译优化参数)。
             Stack manifests (stack.xml):提供关于Stack元数据,包括它的许可信息和Stack之间依赖关系。

    四、  社区级

            ROS的社区级概念是ROS网络上进行代码发布的一种表现形式。结构如下图所示:

            代码库的联合系统。使得协作亦能被分发。这种从文件系统级别到社区一级的设计让独立地发展和实施工作成为可能。正是因为这种分布式的结构,似的ROS迅速发展,软件仓库中包的数量指数级增加。

    参考资料:
    (1)《开源机器人操作系统——ROS》 张建伟等著
    (2)《an open-source Robot Operating System》 paper
    (3)  willowgarage公司网站:http://www.willowgarage.com/
    (4)  ROS官方wiki:http://www.ros.org

    ----------------------------------------------------------------




    ROS探索总结(三)——ROS新手教程


    前面我们介绍了ROS的特点和结构,接下来就要开始准备动手感受一下ROS的强大了。ROS官网的wiki上针对新手的教程很详细,最好把所有的新手教程都搞清楚,这是后面开发最基础的东西。尽管如此,ROS对于新手来说还是很难上手,这里,我就来总结一下我当时学习的历程,也为其他新手作为一个参考。

    一、ROS的安装


            ROS的安装当然是我们开始动手的第一步了,这里我们使用的操作系统是ubuntu,因为ROS在ubuntu上的支持是最好的。
            如果是新手,我建议使用”apt-get“的方法进行安装,不走很简单,按照wiki上说的,大概半个小时就可以安装完毕完全版的ROS:(现在最新版的ROS是groovy,但是我还是习惯使用fuerte)

            如果想挑战源码编译,当然也没有问题:

            安装完毕之后运行一下“roscore”,如果没有问题,安装就成功了!

    注:groovy版本的安装:
                源码编译:http://www.ros.org/wiki/groovy/Installation/Source

    二、ROS的新手教程


            wiki上的新手教程还是很详细的,对代码都有解释,新手一定要把这些例子和代码搞明白:

            上面的教程都是英文的,如果感觉略有压力(本人就是),可以参考下面这两个博客中的部分翻译:

               不过往后面的学习都是英文的资料了,还是要努力适应看英文的文档。
            ROS使用的编程语言主要是C++和python,所以也有针对这两种语言的功能包roscpp和rospy,这两个包的教程与上面的教程基本相似,看完上面的教程也可以看看这两个包的教程:

            努力学习完上面的这些教程,你至少应该明白ROS里面的节点和消息是干什么用的了吧,如果还没理解,那就再多看几遍吧!

    三、ROS中的常用功能

             ROS中提供了很多强大的功能,我们学习完上面的基本知识之后要继续进行深入。

             1、rviz       

             rviz是ROS中一款强大的3D可视化工具,这个玩意在后面可是要频繁用到的,是必须要弄明白的,详细的教程可以参考wiki:
      
             我们可以在里面创建自己的机器人,并且让机器人动起来。还可以创建地图,显示3D点云等等,总之,想在ROS中显示的东东都可以在这里显示出来。当然这些显示都是通过消息的订阅来完成的,机器人通过ROS发布数据,rviz订阅消息接收数据,然后显示,这些数据也是有一定的数据格式的,可以参考下面的链接:

                 
                   看到上面的机器人了吧,是不是很酷,在rviz中,这样的机器人模型是通过urdf文件描述的,具体urdf文件怎么写,参考wiki:

              2、tf

              tf是ROS中的坐标变换系统,在机器人的建模仿真中经常用到。

             ROS中主要有两种坐标系:
            (1)固定坐标系:用于表示世界的参考坐标系;
            (2)目标坐标系:相对于摄像机视角的参考坐标系。
            教程见:http://www.ros.org/wiki/tf

            3、gazebo

            这个工具是ROS中的物理仿真环境,gazebo本身就是一款机器人的仿真软件,基于ODE的物理引擎,可以模拟机器人以及环境中的很多物理特性,这个软件可以稍作了解,并不是后面开发所必须要的。

    四、ROS常用机器人

            1、PR2


                看ROS的应用时,最常见到的机器人就是PR2。这个机器人是ROS的主要维护者(Willow Garage)针对ROS量身定做的机器人,有两个运行ubuntu和ROS的电脑,和两个机器臂以及很多牛逼的传感器,功能是非常强大的,但是售价那是相当的昂贵,国内很少见到,基本都是在国外的研究所里。这款机器人的ROS包比较多,从仿真到导航,所以代码具有比较高的参考价值,当然新手还是先看看其他机器人的代码再来挑战PR2吧,代码比较庞杂。

            2、TurtleBot      


                这个机器人应该算是应用ROS小型移动机器人的典型代表了,资料、文档和代码比较多,主要在建立模型和导航定位方面,代码比较容易理解,可以作为新手参考的最佳机器人了,上面rviz中显示的那个机器人就是它了。

            3、Husky、Erratic

          
                    这两款机器人和TurtleBot机器人差不多,都是小型的轮式移动机器人,同样可以作为新手学习的参考:

                    这些教程和机器人基本都是我当时学习的时候研究和了解过的,总结在此也让那些比较迷茫的初学者作为参考,可以尽快了解和掌握ROS。再次强调一下,wiki上的新手教程是一定要先熟悉的,后面的内容在后续学习过程中可以一边做一边学习。
             *此文只代表个人观点,仅作为参考

    ----------------------------------------------------------------


    欢迎大家转载我的文章。

    转载请注明:转自古-月

    http://blog.csdn.net/hcx25909


    展开全文
  • iOS总体框架介绍和详尽说明

    千次阅读 2015-12-18 10:31:58
    总体介绍iOS为应用程序开发提供了许多可使用的框架,并构成IOS操作系统的层次架构,分为四层,从上到下依次为:Cocoa Touch Layer(触摸UI层)、MediaLayer(媒体层)、Core Services Layer(核心服务层)、Core OS ...

    总体介绍

    iOS为应用程序开发提供了许多可使用的框架,并构成IOS操作系统的层次架构,分为四层,从上到下依次为:Cocoa Touch Layer(触摸UI层)、MediaLayer(媒体层)、Core Services Layer(核心服务层)、Core OS Layer(核心OS层)。

    低层次框架提供IOS的基本服务和技术,高层次框架建立在低层次框架之上用来提供更加复杂的服务和技术,较高级的框架向较低级的结构提供面向对象的抽象。
    在开发应用时应尽可能使用较高级的框架。如果要开发的国内在高层框架中没有提供,你也可以使用较低层框架和技术。

    Foundation和 UIKit框架是应用编程用到的两个主要的框架,能够满足大多数应用程序的开发需求。

    UIKit框架提供的类,用于创建基于触摸的用户界面。所有 iOS 应用程序都是基于 UIKit, 没有这个框架,就无法交付应用程序。UIKit提供应用程序的基础架构,用于在屏幕上绘图、处理事件,以及创建通用用户界面及其中元素。UIKit还通过管理屏幕上显示的内容,来组织应用程序。

    Foundation框架为所有应用程序提供基本的系统服务。应用程序以及 UIKit和其他框架,都是建立在 Foundation 框架的基础结构之上。 Foundation框架提供许多基本的对象类和数据类型,使其成为应用程序开发的基础。它还制定了一些约定(如用于取消分配等任务),使代码更加一致,可复用性更好。

    整个框架架构图如下:
    这里写图片描述


    一、Cocoa Touch Layer(触摸UI层)

    CocoaTouch Layer包含创建ios应用关键的框架。该层包含的框架定义应用的外观,也提供基本的应用基础和关键的技术支持,例如多任务、触摸输入、推送通知和许多其它的高级系统服务。在开发应用时,应当首先研究该层的技术和技术看是否能够满足需要。

    Cocoa Touch Layer包含如下关键技术

    1、AirDrop

    AirDrop允许用户与附近设备共享图片、文档、urls链接以及其它种类的数据。

    2、Text Kit

    TextKit是处理文本和排版的一个全功能、高级别的类集合。使用Text Kit你能在段落、列或者页上对带有风格的文本进行布局;也能在任意区域(如图形)周围布局流动的文本;还能用它来管理多种字体。
    开发应用时应该首先考虑使用Text Kit来进行文本呈现,而不是Core Text。Text Kit与所有UIKit中的基于文本的控制集成允许应用更容易地创建、编辑、显示和存储文本。

    3、UIKit Dynamics

    UIKit dynamics用来为符合UIDynamicItem协议的UIView对象或其它对象规定动画行为。通过在应用的UI中集成真实世界行为和特性进,动画行为为应用提供了一种增强用户体验的方式。

    4、Multitasking

    在ios中多任务用来设计来使电池使用时间最大化。

    5、Auto Layout

    自动布局帮助你使用非常少的代码来建立动态接口。
    使用AutoLayout定义如何在用户接口上布局元素的规则,这些规则表达了视图类之间的关系,如规定一个按钮总是处于它的父窗口的左边缘20个点。
    在Auto Layout中使用的实体是被称为constraints的Objective-C对象。

    6、Storyboards

    串联图 是设计应用用户接口的推荐方式。串联图让你在一个地方就能够设计全部的用户接口,方便在一个位置看到所有的视图和视图控制器以及理解它们是如何一起工作的。串联图的一个重要的部分是定义segues(segues是从一个视图控制器到另一个的转换)。这些转换代表用户接口之间的交互。你可以使用XCOE来可视的定义这些转换或者通过编程启动它们。
    你能使用一个单串联图文件来存储所有的应用视图控制器和视图,或者使用多个视图串联图文件来组织用户接口。
    在应用建立时间,Xcode读取串联图文件的内容并把它分成多个能独立加载的离散的片断,以便获得更好的性能。UIKit框架提供了相应的类来从程序中存取一个串联图的内容。

    7、UI State Preservation

    UI状态保存能够使应用表现的一直运行,从而为用户提供无缝的体验。如果系统遇到内存压力,系统可能安静地强制停止一个或多个后台应用。
    当应用从前台移到后台时,该服务能保存应用的视图和视图控制器的状态。在下次应用重新启动时,能够使用先前保存的状态信息来恢复视图和视图控制器到它们先前的配置,使应用表现得好像一直在运行。

    8、Apple Push Notification Service

    苹果的推送通知服务提供了一种提示用户关于新信息的方式,即使应用当前不在激活运行状态。使用该服务,你能推送文本通知,在应用图标上增加一个标记或者在任意时间触发声音提示。这些消息让用户知道他们应该打开应用来接收相关信息。自Ios7开始,你甚至能推送无声的通知来让应用知道有了新的内容可以下载。
    为了使用IOS应用的推送通知,用户需要做两部分的工作:
    第一、应用必须登记该通知服务以及在通知被提交时处理相关的通知数据。
    第二、你必须提供一个服务端的进程来产生通知。服务端的进程可以使用你自己的本地服务器或者使用苹果的推送通知服务。

    9、Local Notifications

    本地通知作为推送通知机制的补充,可以给应用提供一种不依赖外部服务器产生本地通知的方式。
    运行在后头的应用能使用本地通知作为当重要的事件发生时引起用户注意的一种方式。例如,运行在后台的导航应用能使用本地通知来提示用户什么时间该转弯了。
    应用也能调度本地通知在将来的时间提交以及使那些通知在应用不运行也能被提交。
    本地通知的一个优点是它们与你的应用是独立的。在一个通知已被调度,系统管理它的提交。另外当通知被提交时你的应用甚至不必运行。

    10、Gesture Recognizers

    手势识别用来检测通常类型的手势。由于手势识别使用与系统检测手势相同的试探方法,因此手势识别为应用提供了一个一致的行为。为了使用它,你能在你的视图上附加手势识别功能和并给它提供一个在手势出现时要执行的方法。
    手势识别跟踪原始的触摸事件和确定它们什么时候与想要的手势匹配。

    11、System View Controllers

    许多系统框架为标准的系统接口定义了视图控制器。只要有可能,为了呈现一致的用户体验,就应该使用系统提供的视图控制器而不是创建一个新的。

    Cocoa Touch层框架

    1、Address Book UI Framework(地址本UI框架)

    该框架提供一个面向对象的编程接口。用来显示标准的系统接口,来创建新的联系人和编辑和选择已存在的联系人。

    2、Event Kit UI Framework(月历事件UI框架)

    该框架提供一个视图控制器来呈现标准的系统接口,来观察和编辑月历相关的事件。EventKit UI Framework基于Event Kit framework框架。

    3、Game Kit Framework(游戏工具框架)

    该框架实现对游戏中心的支持,让用户能够在线共享他们的游戏相关的信息。

    4、iAd Framework(iAD框架)

    该框架用来在应用中提供广告条。当你想要显示广告时,广告条与用户UI上的标准的视图进行合并。
    这些视图与苹果的iAd服务一起工作,自动处理、加载和呈现富媒体广告以及应答在那些广告条上的点击等所有相关的工作。

    5、Map Kit Framework(地图工具框架)

    MapKit提供与应用的UI组合的一个可滚动的地图。
    除了显示一个地图,你能使用该框架接口来定制地图的内容和外观,也能使用注解来标记感兴趣的点,也能使用定制的内容来与地图内容叠置。例如,你可以在地图上来画一条公交路线,或者使用注解来高亮显示附近的商店和餐馆。
    除了显示地图,MapKit框架还能与地图应用以及苹果的地图服务器集成来为用户指引方向。
    地图应用能够给任意支持方向的应用提供方向的代理。如提供特定类型方向的应用,例如一个显示地铁路线的应用,能登记请求接收地图应用提供的方向。
    应用也能向苹果的服务器请求步行或驾驶方向,并与他们定制的方向的路径信息混合来为用户提供完整的点到点体验。

    6、Message UI Framework( 消息UI框架)

    该框架用来在应用中提供编辑邮件和sms消息的支持。
    编辑支持包括一个呈现到你的应用的视图控制器接口,并能设置这个视图控制器的一些区域,如接收人、主题、邮件主体和邮件想包括的任意附件。
    在呈现视图控制器后,也能为用户提供一个在发送邮件之前可以编辑邮件的选项。

    7、UIKit Framework

    该框架提供实现图形和事件驱动的应用的至关重要的基础。包括:
    1)基本的应用管理和基础设施,包括应用的主循环;
    2)用户接口管理,包括对storyboards和nib文件的支持;
    3)一个用来封装用户UI内容的视图控制器模式;
    4)标准v系统视图和控制对象;
    5)提供处理触摸和运动事件的支持;
    6)支持包括与iCloud集成功能的文档模式;
    7)图形和窗口支持,包括支持外部显示器;
    8)多任务支持;
    9)打印支持;
    10)定制标准UIKit控制的外观;
    11)支持文本和web内容;
    12)剪切、复制、粘贴的支持;
    13)支持动画UI;
    14)通过url语义和框架接口与系统提供的其它应用集成的能力;
    15)对有障碍用户的可存取性的支持;
    16)支持ApplePush Notification服务;
    17)本地通知调度和提交;
    18)pdf 创建;
    19)支持定制像系统键盘行为一样的用户输入视图;
    20)支持创建与系统键盘交互的定制的文本视图;
    21)支持通过email,Twitter, Facebook和其它服务共享内容。
    也支持一些设备特定功能的集成,例如
    1)内建的摄像机;
    2)用户的图片库;
    3)设备名和模式信息;
    4)电池状态信息;
    5)接近传感器信息;
    6)来自附件耳机的远程控制信息


    二、MediaLayer(媒体层)

    媒体层包含在应用中实现多媒体体验的图形、声音、视频技术和框架。使用这层的技术可以使你容易的建立更加好看和好听的应用。

    包含的关键技术

    1、图形技术

    高质量的图形是所有应用的重要的组成部分。IOS提供了许多帮助你定制艺术和图形屏幕的技术。IOS图形技术为其提供了广泛的支持,并可以与UIKit视图架构无缝工作。
    你能使用标准的视图来快速提交高质量的接口,或者使用本层的图形技术创建你自己的定制视图来提交一个更加丰富的图形体验。
    1)UIKit graphics
    UIKit定义的绘制图像和Bézier路径,以及动画视图内容的高级别技术。
    UIKit视图提供快速和有效的方式来呈现图像和文本内容。
    UIKIT视图也能通过显示和使用UIKitdynamics技术进行动画,并为用户提供反馈,促进用户交互。
    2)CoreGraphics 框架
    CoreGraphics也称作Quartz,是对定制的2D向量和图像呈现提供支持的本地绘制引擎。
    该框架提供的引擎虽然没有OpenGLES引擎速度快,但该框架能够很好地适合于呈现定制的2d图形和动态图像。
    3)CoreAnimation框架
    CoreAnimation也是Quartz核心框架的一部分,是优化应用动画体验的基础技术。
    UIKit视图基于 Core Animation提供视图级别的动画支持。当你想对动画行为有更多控制时也能直接使用CoreAnimation。
    4)Core Image
    CoreImage提供非破坏的方式操作视频和静态图像。
    5)OpenGL ES及GLKit
    OpenGLES使用硬件加速接口来处理先进的2d 和3d 呈现。OpenGLES通常由游戏开发者或想实现沉浸式图像体验的开发者使用。
    OpenGLES框架提供对呈现过程的全部控制,以及提供创建平滑动画所需要的帧速。
    GLKit是一组Objective-C类,以便能够使用面向对象接口来提供OpenGL ES的强大能力。
    6)Text Kit和CoreText
    Text Kit是UIKit框架的家族,用来来执行最好的排面和文本管理。如果你的应用实现先进的文本操作,Text Kit提供与应用视图的无缝集成。
    CoreText是处理先进排面和布局的低级别的c语言框架。
    7)Image I/O
    ImageI/O提供读写大多数图像格式的接口。
    8)Assets Library
    AssetsLibrary框架让你存取用户的图片、视频和媒体。你想在应用中集成用户自己的内容时可以使用该框架。

    2、 声音技术

    声音技术工作于底层硬件之上,为用户提供更加丰富的声音体验。这些体验包括播放和记录高质量的声音、处理MIDI内容以及使用设备内建的声音 等能力
    1)Media Player framework
    该框架是一个高级别的框架, 用来为用户提供对iTunes库存取的容易方式,也提供对播放轨迹和播放列表的支持。当你想快速在应用中集成声音以及不需要控制播放行为时可以使用该框架。
    2)AV Foundation
    AVFoundation是管理声音以及视频播放和记录的面向对象接口。在记录声音和想对声音播放过程有更好的控制时可以使用该框架。
    3)OpenAL
    OpenAL是一个提供位置音效的跨平台的工业标准技术和接口。游戏开发者经常使用该技术来提供高质量的声音。
    4)Core Audio
    Core Audio是一组简单和智能的接口来记录和播放声音以及MIDI内容。在需要对声音有更好控制时使用该框架。

    3、视频技术

    视频技术提供管理应用中的静态视频内容或者播放来自Internet的视频流的支持。对于带有适当的记录硬件的设备,该框架还能够记录视频以及与应用进行集成。
    1)UIImagePickerController
    UIImagePickerController是一个选择用户媒体文件的UIKit视图控制器。
    2)Media Player
    MediaPlayer框架提供一组呈现视频内容的简单易用的接口,该框架支持全屏和小窗口视频播放,也为用户提供可选的播放控制。
    3)AVFoundation
    AVFoundation提供先进的视频播放和记录能力。
    在需要对视频呈现和记录有更多的控制时使用该框架,例如在实时应用中分层显示实时视频和应用提供的其它内容。
    4)CoreMedia
    CoreMedia框架为操作媒体定义低级别的数据类型和接口。
    当你需要对视频内容有无比的控制时可以使用该框架。

    4、AirPlay技术

    AirPlay让应用串流声音和视频内容到Apple TV或者串流声音内容到第三方扬声器和接收器。
    AirPlay内建于许多框架,包括UIKit、Media Player、AVFoundation、Core Audio。因此在大多数情况你不需要为了支持它做任何事。在使用那些框架时,当播放内容时自动获得AirPlay支持。当用户选择使用AirPlay播放内容时系统自动进行路由。

    包含的框架

    MediaLayer提供如下框架和服务。

    1、Assets Library 框架

    AssetsLibrary 框架(AssetsLibrary.framework)提供对用户设备上图片应用管理的图片和视频的存取。
    使用该框架来存取用户保存的图片相册或导入到设备的任意相册中的图片,你也能保存新的图片和视频到用户的图片相册。

    2、AV Foundation 框架

    AVFoundation 框架 (AVFoundation.framework)提供一组播放、记录和管理声音和视频内容的Objective-C类。当你想在应用的ui接口无缝集成媒体能力时使用该框架。你也能使用它来进行更先进的媒体处理,例如同时播放多个声音或者控制播放和记录过程的多个方面。
    该框架提供的服务包括:
    1)声音会话管理,包括对系统声明你的应用声音能力;
    2)对应用媒体资源的管理;
    3)对编辑媒体内容的支持;
    4)捕捉声音和视频的能力;
    5)播放声音和视频的能力;
    6)轨迹管理;
    7)媒体元数据的管理;
    8)立体拍摄;
    9)声音之间的精确同步;
    10)提供一个确定声音文件细节内容的Objective-C接口,例如数据格式,采样率,通道数;
    11) 通过AirPlay串流内容。

    3、Core Audio 框架

    Core Audio是一个对声音处理提供本地支持的框架家族。这些框架支持声音的产生、记录、混合和回放。你也能使用这些接口处理MIDI内容以及串流声音和MIDI内容到其它应用。
    Core Audio框架包括如下框架:
    1)CoreAudio.framework
    定义Core Audio框架使用的所有数据类型。
    2)AudioToolbox.framework
    提供声音文件和声音流的播放和记录服务。也提供管理声音文件,播放系统警告声音,在某些设备上触发震动的支持。
    3)AudioUnit.framework
    提供使用内建声音单元。也提供使你的应用的声音内容作为对其它应用可视的声音组件的支持。
    4)CoreMIDI.framework
    提供与MIDI设备通讯的标准方式,包括硬件键盘和合成器。你使用这个框架来发送和接收MIDI消息以及与通过dock连接器或网络连接到IOS设备的MIDI外设交互。
    MediaToolbox.framework 提供对声音tap接口的存取。

    4、Core Graphics 框架

    CoreGraphics.framework包含Quartz 2D绘制api。
    Quartz是一个原先用在OS X的先进的、向量绘制引擎。Quartz支持路径绘制,抗锯齿呈现,剃度,图像,颜色,坐标空间转换以及pdf 内容创建、显示和分析等功能。
    虽然这个api是C-based接口,但它使用了面向对象抽象来表现基本的绘制对象,因此使它容易存储和重用图形内容。

    5、Core Image 框架

    CoreImage 框架(CoreImage.framework)提供一组强大的内建过滤器来操作视频和静态图像。
    你能在触摸弹起、纠正图片以及面部和特征检测等许多方面使用这些内建的过滤器。这些过滤器的先进特点是它们操作在非破坏方式,即原先的图像不被改变。
    这些过滤器针对底层硬件进行了优化,因此它们是快速和有效的。

    6、Core Text 框架

    CoreText 框架 (CoreText.framework)提供一个对文本进行布局和字体处理的简单的、高性能的C-based接口。
    该框架用在不使用TextKit但仍想获得在字处理应用中发现的先进文本处理能力。
    该框架提供了一个智能的文本布局引擎,包括在其它内容周围环绕文本的能力,它也支持使用多种字体和呈现属性的先进的文本风格。

    7、Core Video 框架

    CoreVideo 框架 (CoreVideo.framework)为Core Media框架提供缓冲和缓冲池支持。多数应用从不直接使用该框架。

    8、Game Controller 框架

    GameController 框架 (GameController.framework)让你在应用中发现和配置针对iPhone/iPod/iPad设备的游戏控制器。
    游戏控制器可以是物理连接到iOS设备或者是通过蓝牙无线连接。GameController框架当控制器可获得时通知你的应用让应用可以规定哪个控制器输入与你的应用相关。

    9、GLKit 框架

    GLKit框架 (GLKit.framework)包含一组简化创建OpenGLES应用的Objective-C based 单元类。
    GLKit支持应用开发的四个关键领域
    1)GLKView和GLKViewController类提供一个OpenGLES视图和其呈现循环的标准实现。
    OpenGLES视图代表应用管理底层的framebuffer对象。应用只需在视图上绘制。
    2)GLKTextureLoader类提供在你的应用中使用图像转换和加载线程,允许应用自动加载纹理图像到应用的上下文。
    能够异步或同步加载纹理。当异步加载纹理时,应用应提供一个完成处理块,该处理块在纹理加载进应用上下文时被调用。
    3)GLKit框架提供向量、矩阵和3d 旋转以及提供OpenGLES 1.1上的矩阵。
    4)GLKBaseEffect,GLKSkyboxEffect,和GLKReflectionMapEffect类实现给通用图形操作提供可配置的图形着色。尤其GLKBaseEffect类实现了OpenGL ES 1.1规范上的光亮和材质模式,简化了移植一个应用从OpenGL ES 1.1到OpenGL ES最后版本的努力。

    10、Image I/O 框架

    ImageI/O 框架(ImageIO.framework)提供输入和输出图像数据和图像元数据的接口。
    该框架利用CoreGraphics数据类型和功能,并支持在ios 上所有的可获得的标准的图像类型。你能使用这个框架存取Exif和IPTC元数据属性。

    11、Media Accessibility 框架

    MediaAccessibility 框架 (MediaAccessibility.framework)管理媒体文件中closed-caption内容的呈现。
    该框架与新的设置配合工作可以让用户决定是否允许closed-caption显示。

    12、Media Player 框架

    MediaPlayer 框架(MediaPlayer.framework)提供应用中播放声音和视频的高级别支持。
    能够使用该框架做如下工作:
    1)播放视频到用户屏幕或通过AirPlay到另外的设备屏幕。能够全屏幕播放视频或以可改变视图大小的方式播放。
    2)存取用户的iTunes音乐库。能够播放音乐轨迹和播放列表、搜索音乐、给用户提供一个媒体picker呈现接口。
    3)配置和管理电影的回放。
    4)在锁定屏幕和app 切换窗口上显示NowPlaying信息。当内容通过AirPlay提交时还能显示到AppleTV上。
    5)检测视频通过AirPlay被串流的时间。

    13、OpenAL 框架

    OpenAudio Library (OpenAL)接口是用来在应用中提供位置音效的跨平台的标准。能够使用该接口在游戏和其它需要位置音效输出的程序中实现高性能、高质量的声音。
    因为OpenAL是跨平台的标准,在iOS使用OpenAL编写的代码能够容易地移植到许多其它平台。

    14、OpenGL ES 框架

    OpenGLES 框架 (OpenGLES.framework)提供绘制2d和3d内容的工具, 它是一个C-based的框架。
    该框架以最接近设备硬件的方式为全屏沉浸式应用例如游戏提供细粒度的图形控制和高的帧率。你能够与EAGL配合使用这个框架,为OpenGL ES 绘制调用和UIKit的本地窗口对象之间提供接口。
    该框架支持OpenGLES 1.1, 2.0, 3.0规范。2.0规范增加了片段和顶点着色的支持,3.0规范增加了更多的功能,包括多个呈现目标和变换反馈。

    15、Quartz Core 框架

    QuartzCore 框架(QuartzCore.framework)包含Core Animation接口。Core Animation是一个先进的复合技术,使用它能容易创建快和有效的view-based的动画。 复合引擎利用底层硬件来有效的实时操作视图内容。只需规定动画的起始点,CoreAnimation做剩下的工作。因为Core Animation内嵌在UIView架构的底层,因此它总是可用的。

    16、Sprite Kit 框架

    SpriteKit 框架 (SpriteKit.framework)框架为2d和2.5d游戏提供硬件加速的动画系统。
    SpriteKit提供大多数游戏需要的基础,包括一个图形引擎和动画系统,声音播放支持,一个物理仿真引擎。 使用SpriteKit不需你自己创建这些事情,使你聚焦在内容设计和内容的高级别的交互上。
    在Sprite Kit应用中内容组织为场景。一个场景包括纹理对象,视频,路径图形,核心图像过滤器和其它的特效。SpriteKit利用这些对象,确定这些对象到屏幕上的最有效的方式。当在场景中到了动画内容的时刻,你能使用SpriteKit来显式规定你想执行的行动或使用物理仿真引擎来为那些对象定义物理行为(例如重力、引力或排拆力)。
    除了SpriteKit框架,也有其它Xcode工具来创建颗粒发射效果和纹理图。你能使用Xcode工具来管理应用资源和快速地更新Sprite Kit场景。


    三、CoreServices Layer(核心服务层)

    CoreServices Layer包含应用需要的基础的系统服务。这些服务中的核心是CoreFoundation和Foundation框架,定义了所有应用使用的基本类型。该层也包含独立的技术来支持一些其它功能, 例如位置、iCloud、社交媒体和网络。

    包含的高级功能:

    1、Peer-to-Peer Services(点到点服务)

    这个Multipeer Connectivity框架提供通过蓝牙进行p2p连接的能力。你能使用p2p连接来启动与附近设备的通讯会话。虽然p2p连接主要用在游戏中,你也能在其它类型的应用中使用这个功能。

    2、iCloud Storage(云存储)

    iCloud存储让应用把用户文档和数据写到一个中心位置,用户然后能从他们的计算机和ios 设备存取这些数据。使用iCloud可以使用户文档无所不在,意味着用户能从任何设备阅读或编辑那些文档,而不需要显式的同步或文件传输。存储文档到用户的iCloud账户也为用户提供了一层安全。即使用户的设备丢失,那些设备上的文档如果已经保存到iCloud就不会丢失。
    应用能以两种方式使用 iCloud存储,每一种有不同的使用意图:
    1)iCloud文档存储。
    可以使用这个功能在用户的iCloud账户存储用户文档和数据。大多数应用使用iCloud文档存储来共享来自用户账户的文档。使用iCloud文档存储用户关心的是文档能否能够在设备之间共享以及他们是否能够从一个给定设备查看和管理那些文档。
    2)iCloud键值存储。
    使用这个功能在应用之间共享数据。iCloud键值存储是应用与应用的其它实例共享小量数据(几十k字节)的方式,应用应当用它存储非紧急的应用数据,例如设置。

    3、Automatic Reference Counting(自动引用计数)

    AutomaticReference Counting(ARC)是一个编译级别的功能,用它来简化Objective-C对象生命周期过程的管理,以此代替用户必须记住什么时候应该保持和释放对象。ARC评估对象的生命周期需求和自动在编译时间插入适当的方法调用。
    ARC用来代替ios 的早期版本中存在的传统的管理内存的编程模式。新创建的工程自动使用ARC。XCODE也提供了移植工具帮助你转换遗留的工程来使用ARC.

    4、Block Objects(块对象)

    BlockObjects是一个能够与你的C或Objective-C代码集成的C语言的构造块。一个blockobject本质上是一个异步功能和相关的数据。在其它语言中有时也被称做closure或lambda。Blocks尤其用作回调或放在你需要一种容易的组合执行代码和相关数据方式的地方。
    在ios,通常在下面的场景使用Blocks:
    1)作为代理或代理方法的代替;
    2)作为回调功能的代替;
    3)为某个一次性操作实现其完成处理函数;
    4)在一个集合中的所有项上执行一个任务;
    5)与提交队列一起执行异步任务。

    5、Data Protection(数据保护)

    DataProtection允许应用利用设备上已有的内建的加密方法来使用用户的敏感数据。
    当应用指定一个特定的文件被保护时,系统在磁盘上以加密格式存储该文件。当设备锁定时,该文件的内容不能被应用和任何潜在的侵入者存取。可是当设备由用户解锁时,一个解密key被创建允许你的应用存取那个文件。
    用户也可以使用其它级别的数据保护机制。实现数据保护需要你考虑如何创建和管理你想保护的数据。应用必须设计在数据的创建时间加密数据,以及当用户锁定或解锁设备时为存取条件改变做好准备。

    6、File-Sharing Support(文件共享支持)

    File-SharingSupport使用户数据文件在iTunes 9.1和以后上可被其它应用获得。一个应用声明支持文件共享使它的/Documents目录下的内容对其它用户可获得。用户然后当需要时能够把文件从iTunes移进或移出应用的Documents目录。这个特征不允许应用与相同设备上的其它应用共享应用,这需要粘贴板或一个文档交互控制器对象。
    应用为了允许文件共享支持,需要做如下工作:
    1)在应用的Info.plist文件中增加UIFileSharingEnabled键,并设置其值为YES。
    2)在你的应用的Documents中放你想共享的文件;
    3)当设备插进用户的计算机时,iTunes在选中设备的Apps标签下显式一个文件共享节;
    4)用户然后能够增加文件到设备的文档目录或移动文件到桌面。
    支持文件共享的应用应该能够识别文件什么时候增加到其Documents目录和做出适当的应答。例如应用可以使任意新文件的内容可以从它的接口获得。也应该从不把Documents目录的文件列表呈现给用户来请求用户决定对那些文件做什么。

    7、Grand Central Dispatch

    GrandCentral Dispatch(GCD)是一个BSD技术,应用可以用来管理其任务的执行。
    GCD与高优化的核组合成一个异步编程模式,来提供方便和更有效的对线程的替代。GCD也为许多低级别的任务提供一个方便的选择,例如读和写文件描述符,实现定时器和监视信号和处理事件。

    8、In-App Purchase(应用内购买)

    In-App Purchase 提供在应用中销售应用特定的内容和服务以及来自iTunes的内容的能力。
    这个功能使用StoreKit框架实现,并提供使用用户的iTunes账号来处理金融方面的事务需要的基础。应用处理全部用户体验和供购买的内容及可获得服务的呈现。作为可下载的内容,你能把可下载的内容放到你自己的服务器或使用苹果的服务器。

    9、SQLite

    SQLite库让你在你的应用中嵌入一个轻量级的sql数据库,而不需要运行一个分离的远程数据库服务进程。从你的应用,你能创建本地数据库文件,管理数据库表和表中的数据记录。
    SQLite库为通用功能使用设计,但已经被优化来提供对数据记录更快速的存取。

    10、XML Support

    Foundation框架提供一个NSXMLParser类用来从一个xml文档中引出元素。
    操作xml内容的额外的支持由libxml2库提供支持。libxml2开源库让你快速地分析或写任意的xml数据和转换xml内容到html.

    核心服务框架(Core Services Frameworks)

    Core Services Frameworks包含下面的一些框架。

    1、Accounts Framework(帐户框架)

    Accounts框架 (Accounts.framework)为确定的用户账号提供单点登录模式。
    单点登录通过消除用户分离的多个账号需要的多次登录提示,来增强用户体验。它也通过为应用管理账号认证过程来简化开发模式。
    该框架需要与Social框架配合使用。

    2、Address Book Framework(地址本框架)

    AddressBook 框架(AddressBook.framework)提供可编程存取用户的联系人数据库的方式。
    如果应用使用联系人信息,你能使用该框架来存取和修改联系人信息。例如一个聊天应用可以使用该框架来引出可能的联系人列表,通过联系人列表来启动一个会话以及在特定视图显示那些联系人。
    重要提示:存取用户的联系人数据需要用户的明确的许可。应用因此必须准备好用户拒绝存取的情形。应用也鼓励提供Info.plist键来描述需要存取的原因。

    3、Ad Support Framework(广告支持框架)

    AdSupport 框架 (AdSupport.framework)提供存取应用用于广告功能的一个标识。
    该框架也提供一个指示用户是否选择广告跟踪的标志。应用在试图存取广告标识前需要度和判断这个标志。

    4、CFNetwork 框架

    CFNetwork框架 (CFNetwork.framework)是高性能的使用面向对象对网络协议进行抽象的一组C-based接口。这些抽象提供对协议栈细节的控制,使它容易使用低级别的构造例如BSDsockets。
    你能使用该框架简化与ftp或http服务器通讯或决定dnshosts的任务。使用CFNetwork 框架,你能:
    1、使用BSD sockets。
    2、使用SSL或TLS创建安全连接。
    3、决定dnshosts。
    4、与HTTP服务器、认证HTTP服务器、HTTPS服务器交互。
    5、与FTP服务器交互。
    6、发布、解决和浏览Bonjour服务。
    CFNetwork物理和理论上基于BSD sockets。

    5、Core Data 框架

    CoreData 框架 (CoreData.framework)框架是管理MVC应用中的数据模式的一种技术。
    CoreData框架打算在数据模式是高结构化的应用中使用。代替编程定义数据结构,在xcode中能够使用图形工具来建立一个表现你的数据模式的纲要。在运行时,你的数据模式实体的实例通过CoreData框架被创建、管理和获得。
    通过为你的应用管理其数据模式,CoreData大大减少了必须书写的代码量。CoreData也提供如下功能:
    1)为优化性能在SQLite数据库中存储对象数据;
    2)一个管理数据表视图结果的 NSFetchedResultsController类;
    3)对基本的文本编辑之外的undo/redo的管理;
    4)支持属性值的校验;
    5)支持传播改变确保对象之间的关系保持一致性;
    6)支持分组、过滤和在内存中优化数据。
    如果你开始开发一个新应用或计划对已有应用进行大的更新,应该考虑使用CoreData。

    6、Core Foundation 框架

    CoreFoundation 框架 (CoreFoundation.framework)是一组C-based接口,为ios应用提供基本的数据管理和服务功能。该框架包括如下支持:
    1)集合数据类型(数组、集合等等);
    2)应用打包Bundles;
    3)字符串管理;
    4)日期和时间管理
    5)原始数据块管理
    6)Preferences管理;
    7)URL和流操作;
    8)线程
    9)端口和socket通讯。
    CoreFoundation框架与Foundation框架紧密相关,为相同的基本功能提供Objective-C接口。当你需要混合使用Foundation对象和Core Foundation类型时,你能利用两个框架之间存在的“toll-freebridging”。toll-free bridging”意味着你能可交换地在两个框架的方法和功能中使用一些CoreFoundation和Foundation类型。这个支持对许多数据类型可用,包括集合和字符串数据类型。每个框架的类和类型描述声明一个对象是否是toll-freebridged以及在是的情况下来标识它连接到什么对象。

    7、Core Location 核心位置框架

    CoreLocation 框架 (CoreLocation.framework)为应用提供位置信息。该框架使用板上的GPS、蜂窝、或者Wi-Fi来定位用户的当前经度和纬度。
    你可在你的应用中集成该技术为用户提供位置信息。例如,你可实现一个基于用户的当前位置搜索附近餐馆、商店或者银行的应用。CoreLocation框架也提供如下能力:
    1)在包括磁力计的ios设备上存取罗盘信息;
    2)基于地理位置或蓝牙beacon进行区域监视;
    3)支持使用蜂窝基站的低耗电的位置监视;
    4)与MapKit配合来增强在特定情景下的位置数据的质量,例如开车时。

    8、Core Media Framework(核心媒体框架)

    CoreMedia 框架(CoreMedia.framework)提供由AV Foundation框架使用的低级别的媒体类型。大多数应用从不需要使用该框架,但少数需要更精确控制音视频内容创建和呈现的开发者可以使用它。

    9、Core Motion Framework (核心运动框架)

    CoreMotion 框架 (CoreMotion.framework)提供一组接口来存取设备上可获得的运动数据。
    该框架支持使用一组新的block-based接口来存取原始和加工过的加速度计数据。对于带有陀螺仪的设备,你也能获得原始的陀螺仪数据和加工过的反应设备方向和旋转速度的数据。
    你能在游戏或其它使用运动作为输入或作为增强用户体验的方式的应用中使用加速度计和陀螺仪两种数据。对于带有计步硬件的设备,你能存取它的数据来跟踪健康相关的运动。

    10、Core Telephony Framework(核心电话框架)

    CoreTelephony 框架 (CoreTelephony.framework)提供与蜂窝电话的通话相关的信息交互的接口。
    可以使用该框架来获得用户的蜂窝服务提供者的信息。对于对蜂窝call事件感兴趣的应用例如VoIP应用也能在那些事件出现时被通知。

    11、Event Kit 框架

    EventKit 框架 (EventKit.framework)提供存取用户设备上的月历事件的接口。能够使用该框架来做如下事情:
    1) 获得用户月历上存在的事件和提示;
    2)增加事件到用户月历;
    3)为用户创建提示和使它们出现在提示应用中;
    4)为月历事件配置提示信号,包括设置提示信号应该什么时候触发的规则。
    重要提示:存取用户的月历和提示数据需要用户的明确许可。应用因此必须准备好用户拒绝的情形,也鼓励应用在其Info.plist文件中提供一个描述需要存取原因的键。

    12、Foundation框架

    Foundation框架 (Foundation.framework)提供Core Foundation框架提供的许多功能的Objective-C封装。该框架提供如下功能的支持:
    集合数据类型(数组、集合等等);
    应用打包Bundles;
    字符串管理;
    日期和时间管理
    原始数据块管理
    Preferences管理;
    URL和流操作;
    线程和运行环;
    Bonjour;
    通讯端口管理;
    国际化;
    规则表达式匹配;
    Cache支持。

    13、JavaScript 核心 框架

    JavaScriptCore 框架 (JavaScriptCore.framework)为许多标准的JavaScript对象提供Objective-C语言的封装。使用该框架来执行JavaScript代码和分析JSON数据。

    14、Mobile Core Services (移动核心服务框架)

    MobileCore Services 框架(MobileCoreServices.framework)定义在通用类型标识符(UTIs)中使用的低级别类型。

    15、Multipeer Connectivity Framework(多方连接框架)

    MultipeerConnectivity 框架 (MultipeerConnectivity.framework)支持附近设备的发现,并与那些设备直接通讯(不需要Internet连接)。
    使用该框架能够与附近设备通讯、容易的创建多人会话、支持可靠地传输顺序和实时数据。
    该框架为发现和管理网络服务提供可编程和UI-based的选项。应用能在ui中集成MCBrowserViewController类来显示一个发现设备列表让用户选择。另外也能使用MCNearbyServiceBrowser类来可编程的查找和管理对方设备。

    16、Newsstand Kit 框架

    Newsstand应用为用户提供了一个阅读杂志和报纸的中心位置。想通过Newsstand提供杂志和报纸内容的出版商能够使用NewsstandKit 框架(NewsstandKit.framework)创建它们自己的iOS应用,让用户启动新杂志和报纸新闻的后台下载。在启动下载后,系统处理下载操作和当内容可获得时通知应用。

    17、Pass Kit 框架

    Passbook应用为用户提供了一个存储订货单、登机卡、入场券和商业折扣卡的位置。代替物理携带这些东西,用户现在能在IOS设备上存储它们,并和过去一样的方式使用。
    Pass Kit 框架 (PassKit.framework)提供把这些功能集成到你的应用的Objective-C接口。
    你能与web接口和文件格式信息组合使用该框架来创建和管理你们公司提供的电子入场券。
    电子入场券由你们公司的web service创建并通过email、Safari或定制的应用提交到用户的设备。电子入场券本身使用特殊的文件格式,在提交之前被加密签名。文件格式标识关于提供服务的相关信息以及用户知道是什么服务的信息。
    电子入场券也可以包含一个对卡进行校验的条码或其它信息,以便它能被兑换或使用。

    18、Quick Look 框架

    QuickLook 框架(QuickLook.framework)提供了一个预览应用不直接支持的文件内容的接口。
    该框架主要打算用于应用从网络下载文件或处理来自不知道来源的文件的工作。
    在得到文件后,你能使用该框架提供的视图控制器来直接显示文件的内容。

    19、Safari Services 框架

    SafariServices 框架 (SafariServices.framework)提供以可编程的方式增加URLs到用户的Safari的书签的支持。

    20、Social Framework(社交框架)

    Social框架(Social.framework)提供一个简单的接口来存取用户的社交媒体账号。
    该框架取代Twitter框架并增加了其它社交账号,包括Facebook、Sina微博以及其它。
    应用能使用该框架提交状态更新和图像到用户账号。该框架与Accounts框架一起为用户提供单点登录并确保存取的用户账号是经过准许的。

    21、Store Kit 框架

    StoreKit 框架 (StoreKit.framework)提供在ios应用中购买内容和服务的支持,也被称作应用内购买。
    例如,你能使用该功能来允许用户去锁另外的应用功能。或者如果你是一名游戏开发者,你能使用它来提供另外的游戏级别。在这两种情况,StoreKit框架处理事务的收入方面事务,包括通过用户的iTunes账号处理付费请求,给应用提供关于购买的信息。
    Store Kit聚集在事务的金融方面,确保事务正确和安全。你的应用处理事务的其它方面,包括购买接口的呈现和适当内容的下载(去锁)。
    工作的分工让你能够控制购买内容的用户体验。由你决定你想呈现给用户什么样的购买接口和什么时候那样做,你也决定你的应用最好的提交机制。

    22、System Configuration Framework(系统配置框架)

    SystemConfiguration 框架(SystemConfiguration.framework)提供可达性接口,你能用它来确定设备的网络配置,也能使用该框架确定一个Wi-Fi或蜂窝连接是否在用以及一个特定的主机服务器是否能够存取。


    四、Core OS Layer(核心OS层)

    CoreOS层包含其它大多数技术建在其之上的低级别的功能。虽然应用不直接使用这些技术,它们被其它框架使用。在需要显而易见的处理安全或与外设通讯的情形,你也能使用该层提供的框架。

    Core OS包含的框架:

    1、Accelerate 加速框架

    Accelerate框架 (Accelerate.framework)包含执行数字信号处理、线性代数、图像处理计算的接口。
    使用该框架的优点是它们针对所有的ios设备上存在的硬件配置做了优化,因此你能写一次代码确保在所有设备上有效运行。

    2、Core Bluetooth Framework(核心蓝牙框架)

    CoreBluetooth 框架 (CoreBluetooth.framework)允许开发者与蓝牙低耗电外设(LE)交互。
    使用该框架的Objective-C接口能够完成如下工作:
    1)扫描蓝牙外设,连接和断开发现的蓝牙外设;
    2)声明应用的服务,转换ios 设备成其它蓝牙设备的外设;
    3)从IOS设备广播iBeacon信息;
    4)保存你的蓝牙连接的状态,当应用重新启动时恢复那些连接;
    5)蓝牙外设可获得性变化时获得通知。

    3、External Accessory Framework(外部附件框架)

    ExternalAccessory 框架(ExternalAccessory.framework)提供与连接到IOS设备的硬件附件通讯的支持。
    附件能通过30-pin连接器或使用蓝牙无线与IOS设备进行连接。该框架给你提供了获得关于每一个可获得的附件信息和启动通讯会话的方式。然后,你可自由的使用附件支持的命令直接操作附件。

    4、Generic Security Services Framework(通用安全服务框架)

    GenericSecurity Services 框架 (GSS.framework)给ios应用提供一组标准安全相关的服务。该框架的基本接口规定在IETFRFC2743 andRFC4401。除了提供标准的接口,IOS还包括一些没有在标准中规定但被许多应用需要的一些管理证书需要的额外东西。

    5、Security Framework(安全框架)

    除了内建的安全功能,IOS也提供了一个明确的安全框架(Security.framework),你能用它来保证应用管理的数据的安全。
    该框架提供管理证书、公有和私有key和信任策略的接口。支持产生加密安全伪随机码。它也支持在keychain(保存敏感用户数据的安全仓库)中保存证书和加密key。
    公共加密库提供对称加密、hash认证编码(HMACs)、数字签名等额外支持,数字签名功能本质上与iOS上没有的OpenSSL库兼容。
    在你创建的多个应用之间共享keychain是可能的。共享使它容易在相同的一套应用之间更平滑的协作。例如,你能使用该功能来共享用户口令或其它元素,否则可能使每个应用都需要提示用户。
    为了在应用之间共享数据,必须为每个应用的Xcode工程配置适当的权限。

    6、System

    System级包含kernel环境、驱动以及操作系统级别的unix接口。kernel本身负责操作系统的每一个方面:如虚拟内存管理、线程、文件系统、网络和互联通信。在该层的驱动也提供在可获得的硬件与系统框架之间的接口。为了安全,对kernel和驱动的存取被限制到一组有限的系统框架和应用。
    IOS提供一组存取许多操作系统低级别功能的接口。应用通过LibSystem库存取这些功能。该C based的接口提供如下功能的支持:
    1) 多任务(POSIX线程和GCD)
    2) 网络(BSDsockets)
    3) 文件系统存取
    4) 标准I/O
    5) Bonjour和DNS服务
    6) 位置信息
    7) 内存分配
    8) 数学计算

    7、64-Bit Support

    IOS原先是为32-bit架构的设备设计的。自iOS 7,开始支持在64-bit进行编译、链接和调试。所有的系统库和框架是支持64位的,意味着它们能在32-bit和64-bit应用中使用。当以64-bit运行时编译时,应用可能运行的更快,因为在64-bit模式可以获得额外的处理器资源。
    iOS使用OS X和其它64-bitUNIX系统使用的LP64模式,意味着在这些系统移植时不会碰到太头疼的事。

    相关内容参考:http://blog.csdn.net/GooHong/article/details/28911301

    展开全文
  • (一)代码框架

    千次阅读 2018-12-13 23:51:09
    个人认为这框架还是非常广泛而经典的,虽然游戏的代码都是我的,但我仍体会到这个框架对团队协作非常的有利,各个层级各做各的,互不相干,但又受到统一的规范管理,多好。。 正题,先百度一波: MVC全名是Model...
  • 安能饭否Android客户端开源代码框架分析 总体框架 任务框架
  • 中央银行数字货币的总体框架

    千次阅读 2020-06-28 18:25:47
    中央银行数字货币的总体框架 1、中央银行数字货币的运行框架 中央银行数字货币的运行框架有两种模式:一种是由中央银行直接面向公众发行数字货币;另一种是遵循传统的中央银行 - 商业银行二元模式。在第一种情形下...
  • Android核心分析(23)-----Andoird GDI之基本原理及其总体框架 2010-06-13 22:49 18638人阅读 评论(18) 收藏 举报 Android GDI基本框架  在Android中所涉及的概念和代码最多,最繁杂的就是GDI相关的...
  • Tor源码分析六 -- 总体框架

    千次阅读 2013-05-10 11:36:46
    1. 客户端的总体框图  由于画框图的过程稍微繁琐,所以框图给出的稍慢了些,请大家见谅。同时,框图画的比较急促,一定会有错误的地方,请大家指正。  框图中给出了客户端Tor系统所使用到的最重要的结构体以及其...
  • ROS新手教程【二】ROS总体框架

    千次阅读 2015-11-30 10:31:27
    一、 总体结构  根据ROS系统代码的维护者和分布来标示,主要有两大部分:  (1)main:核心部分,主要由Willow Garage公司和一些开发者设计、提供以及维护。它提供了一些分布式计算的基本工具,以及整个ROS的...
  • p2psim学习笔记(二) 总体框架流程

    千次阅读 2008-08-04 12:44:00
    程序的总框架图可以在http://pdos.csail.mit.edu/p2psim/p2psim-classes.pdf得到(好像是贴不了图吗... 总体流程说明(网上转载有修改) –先有一个总体认识(1)节点node模拟成运行P2P算法的机器,通过Network相互之间发送
  • Hibernate框架(一)——总体介绍

    万次阅读 多人点赞 2014-03-18 09:40:25
    利用Hibernate框架我们就可以不再编写重复的JDBC代码,不再反复的测试我们的SQL语句的如何。这里这需要我们简单配置,调用框架给我们提供的方法,就可以完成对数据增删改查的,那么Hibernate到底是个什么样的框架...
  • ROS探索总结(二)——ROS总体框架

    万次阅读 多人点赞 2013-04-12 22:23:30
    一、 总体结构  根据ROS系统代码的维护者和分布来标示,主要有两大部分:  (1)main:核心部分,主要由Willow Garage公司和一些开发者设计、提供以及维护。它提供了一些分布式计算的基本工具,以及整个ROS的...
  • Python(TensorFlow框架)实现手写数字识别系统

    万次阅读 多人点赞 2019-07-31 11:27:55
    本文使用Tensorflow框架进行Python编程实现基于卷积神经网络的手写数字识别算法,并将其封装在一个GUI界面中,最终,设计并实现了一个手写数字识别系统。
  • 一简述 通过上一节的介绍,我们已经知道ROS的一些基本特点: 1–ROS—是一个开源的次级操作系统,是一些包,软件工具的集合 2–它跨机器进行通信的体系结构—提供了对系统进行实时数据分析,编程语言独立...二总体结构
  • 2.RT-thread 项目实战--总体框架搭建

    千次阅读 2020-01-11 19:11:47
    硬件上本来打算使用潘多拉开发板,但是恰好公司有个类似的板卡,想要实现的功能都有,就直接用公司的这个板卡了,虽然原理图不能开源,但是框架可以讲清楚,之后用在别的开发板上效果是一样的,接下来详细的讲一下...
  • jetty总体设计框架

    千次阅读 2013-11-07 16:26:29
    jetty的总体设计与http请求处理流程。。。
  • Jetty总体设计框架

    千次阅读 2014-03-02 15:42:42
    其实读jetty的代码到现在,对整个jetty服务器的运行以及实现概况都已经有了大体的了解,这篇文章就先对整个jetty的实现设计做一个简单的概述吧。。。。 先来一张图来描述一下整个jetty服务器的整体结构。。。 ...
  • 一步步带你看懂orbslam2源码--总体框架(一)

    千次阅读 多人点赞 2019-09-30 08:56:22
       谈谈SLAM技术,其实更准确地说来应该是SLAM框架.距今为止,SLAM其实已经发展了近30多年的历史,其理论框架已经大体成熟与定型,基本上都是分为前端视觉里程计,后端基于滤波或者非线性优化,回环检测以及建图等.该...
  • VINS理论与代码详解1——框架解析

    万次阅读 2017-12-05 13:27:06
    VINS理论与代码详解1——框架解析 在前面:本文整和自己的思路,希望对学习VINS或者VIO的同学有所帮助,如果你觉得文章的对你的理解有一点帮助,可以推荐给周围的小伙伴们当然,如果你有任何问题想要交流,欢迎...
  • OpenLayer源代码总体结构分析

    千次阅读 2012-10-07 23:29:37
    OpenLayer源代码总体结构分析    通过前面的项目介绍,我们大概已经知道 Openlayers是什么,能够做什么,有什么意义。接下来我们分析它怎么样,以及怎样实现的等问题。  这个图是从它的文档上截取的,...
  • 一、 总体结构  根据ROS系统代码的维护者和分布来标示,主要有两大部分:  (1)main:核心部分,主要由Willow Garage公司和一些开发者设计、提供以及维护。它提供了一些分布式计算的基本工具,以及整个ROS的...
  • 分析 JUnit 框架代码

    千次阅读 2014-03-15 02:53:32
    理解 JUnit 测试框架实现原理和设计模式 本文细致地描述了 JUnit 的代码实现,在展示代码流程 UML 图的基础上,详细分析 JUnit 的内部实现代码的功能与机制,并在涉及相关设计模式的地方结合代码予以说明。另外,...
  • JUnit4框架代码解析

    万次阅读 2010-11-19 22:39:00
    JUnit4的代码到底是怎么实现的。
  • ATTENTION, LEARN TO SOLVE ROUTING PROBLEMS代码框架 gnenerate_data 首先,我们要搞清楚代码的input的数据到底是什么样的,才能知道后面调用各个方法时候,参数是input的这个东西,到底长什么样。 首先我先看了...
  • SpringMVC(一)——流程框架总体介绍

    万次阅读 多人点赞 2014-03-20 23:18:04
    Spring 框架提供了构建 Web 应用程序的全功能MVC 模块 ,其功能和Strtus2,Struts1是类似的,只不过是实现的原理不同而已。其中Struts2是通过过滤器来实现路劲和action的映射等控制流转功能,而Struts1和SpringMVC则...
  • VINS-Mono视觉SLAM总体设计框架解读

    千次阅读 2019-02-15 10:51:16
    2月15 2月16完成 论文解读 代码解读
  • # 送入x_a,x_b两张图片(来自训练集的不同ID) # 通过st 编码器,编码成两个stcode: # s_a[batch,128,64,32] # s_b[batch,128,64,32] s_a = self.gen_a.encode(self.single(x_a)) s_b = self.gen_b.encode(self....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 99,043
精华内容 39,617
关键字:

代码总体框架怎么写