zoukankan      html  css  js  c++  java
  • objectivec笔记

          1,动态分配

            动态分配由两个函数来处理:malloc和free。使用一个参数来调用malloc以请求内存,该函数指定了所需的字节数。malloc返回指向请求的数目的字节的一个指针,随后可以将这个指针强制转换成想要的数据类型,并且赋给一个变量,而这个变量的类型就是指向所请求的类型的一个指针。曾今,当没有可用的内存分配时,malloc返回NULL,然而,OS X和iOS使用延迟分配,malloc返回所请求的内存一个指针,但是,在执行一段代码来访问该内存之前,系统不会为该请求分配内存资源。结果,如果你多次请求内存,并且没有使用该内存或没有释放该内存,那么malloc可能会返回一个非NULL的值,即便没有更多的内存也如此。在这种情况下,使用返回的指针可能导致程序崩溃。假设给RAM和交换空间指定一些典型值,即便有可能,你也是极少会看到这种情况在OS X系统上发生。在iOS中,遇到这种情况之前,应用程序很可能会从系统接收到一条低内存警告。

          2,编译器指令

            以@字符开头的单词是编译器指令,而不是可执行代码。我们知道,@interface表示一个类定义的接口部分的开始;还有@implementation表示实现部分的开始;还有@end,用来表示这些部分的结束。objective-c使用NSString的常量实例而不是普通的C字符串,而NSString是在Foundation框架中定义的一个类。可以用创建一个C字符串的方式来创建一个NNstring直接量,只不过在字符串开始处添加一个@,例如:

                           "the big apple" // literal C string

                           @"the big apple" //literal NSString

    严格地讲, @"the big apple" 是一条编译指令,它告诉编译器创建一个NSString直接量,其文本为“the big apple”,如果使用带有%@描述符的格式字符串,但是忘记了提供一个对应的对象参数,那么NSLog将尝试向位于对象参数所应该放置的地址的字节发送一条description消息。这通常会导致程序崩溃。

          3,消息

             要求Objective-c对象执行自己的一个方法,这与调用一个函数并不是同样的事情。函数调用通常是静态绑定的,即在运行时所发生的事情,在编译时就已经确定了。当编译器遇到一个函数调用时,它插入一条指令,以跳转到构成函数体的代码。而Objective-c使用一种叫消息的更为动态的系统。当想要objective-c对象执行自己的一个方法时,就向该对象发送一条消息。对象通过执行于该消息对应的方法来做出相应。

           消息的表达式的形式如下:

                【receive message】

             当执行一个消息表达式时,objective-c 运行时检查接收者并确定其类。运行时针对每个类都有一个表,列出了该类定义的方法,并且将每个方法与指向该方法的代码的一个指针关联起来。运行时从消息获取方法名,在接收者的类表中找到相对应的指针,然后使用该指针来执行方法的代码。

            objective-c消息系统时如何工作的?

    具体细节如下:1,所有的objective-c对象知道他们自己的类。要完成这一任务,编译器给每个对象实例添加一个实例变量isa,isa说明一个实例时什么类型的对象。在运行时,isa指向类的一个类结构,这是一种不透明的类型,其中包括了有关类的信息。包括该类所定义的实例变量和方法;并且还有一个指针,指向关于其超类的信息。当启动程序时,这些信息在运行时填充。2,编译器将方法转换为实际编译的C函数。在这一过程中,它在参数列表的开始处添加两个额外的参数,self和_cmd。self时一个指针,指向发送消息时从当接收者的对像;_cmd是消息的方法名称对应的选折器。

             考虑如下的objective-c方法:-(void)dosomething:(int)anarg {....}

    在编译的过程中,编译器将dosomething:转换为一个C函数,它带有如下的参数列表:(id self,SEL _cmd,int anarg)

    每个objective-c类都有一个表,这个表将一个方法的选择器与指向实现该方法的函数的一个指针连结起来。给定了选折器,运行时可以使用这个表来找到匹配的函数的指针。每个类也有一个相关的缓存机制,这加速了对一个给定方法的后续搜索。

           4,什么时运行时?

          作所有事情的运行时到底是什么呢?它一点也不神秘。运行时只是普通C函数和结构的一个共享库。在程序开始运行时,会调用一些这样的函数。这些函数根据编译器放置在你的可执行代码中的信息来构筑表。在执行程序的不同时刻,还会调用其他的函数来查找并操作这些表中的信息。这些函数调用都是编译器自动创建的。

           5,向nil发送消息

        按照objective-c的设计,向一个nil接收者发送一条消息没有任何效果。当计算一个带有nil接收者的表达式时,没有什么方法会执行。程序默默地忽略nil接收者,而不是引发一个异常或崩溃,这允许我们编写整洁的代码。不必像下面这样搞乱了代码的结构而保证不会出错:

    Shape*ashape=...

    if(ashape!=nil) { [ashape draw]; }

    而是可以直接写成:[ ashape draw ];

    如果ashape刚好是nil,就不会绘制什么内容,并且,从下一行代码开始继续执行。如果消息表达式中方法的返回值类型是一个指针或数字类型,则发送给nil的一条消息的返回值是0。对于其他的返回类型(例如,结构),在某些情况下返回值是不确定的,有些地方可能需要使用一个nil接收者来引发一次异常,但是,大多数情况下避免使用if语句将会使代码更整齐。如果在特定的情况下,捕获一个nil接收者很重要,那么你也可以去测试它。

         6,选择器

        一条消息的方法名部分有时候叫做选择器或方法选折器,因为,运行时使用它来选择要执行哪一个方法。选择器只是名称,他们不带有任何类型的信息。Objective-c定义了一个类型,SEL,来保存选择器的表示。SEL与选择器名称有一对一的关系,但是,一个SEL自身并非一个字符串。带有相同名称的所有选择器,具有相同的SEL,并且,不同名称的总是对应不同SEL。在内部,为了提高效率,Objective-c使用SEL类型来表示方法。使用字符串将会很慢,因为仅仅测试两个字符串是否相同,就需要遍历字符串的所有字符。

          7,具有相同名称的方法

        如果使用动态类型(变量类型为id),则具有相同名称的所有方法应该拥有同样的参数类型和返回值,即使他们由不相关的类型声明。如果违反了这一规则将会得到编译器的警告;如果忽略这一警告你的程序可能会有非常细微的bug。

  • 相关阅读:
    阿里P7架构师是如何解决跨域问题的!你有遇到吗?
    Node.js Express 框架
    用户管理 之 Linux 系统中的超级权限的控制
    [转] Exchange 2013 安装部署详解
    Clustered和Nonclustered Indexes 各自得特点和区别及长短处
    配置IIS5.5/6.0 支持 Silverlight
    redis模块使用
    redis介绍及安装
    linux上安装redis、远程配置及开机启动
    远程连接linux、配置SSHD
  • 原文地址:https://www.cnblogs.com/ymy124/p/2369181.html
Copyright © 2011-2022 走看看