美文网首页selector
认识NSObjCRuntime.h

认识NSObjCRuntime.h

作者: 笑破天 | 来源:发表于2019-08-28 22:17 被阅读0次

    先来看NSObjCRuntime.h


    NSObjCRuntime.h

    主要是NSInteger封装、指定初始化方法。下面逐句分析认识:

    5-6行 #ifndef

    #ifndef是"if not defined"的简写。预处理功能中三种(宏定义,文件包含和条件编译)中的第三种——条件编译。防止头文件的重复包含和编译,便于程序的调试和移植。

    在C语言中,主要用来避免重复定义错误。在OC语言中,主要用来调试和移植。

    假如你有一个C源文件,它包含了多个头文件,比如头文件A和头文件B,而头文件B又包含了头文件A,则最终的效果是,该源文件包含了两次头文件A。如果你在头文件A里定义了结构体或者类类型(这是最常见的情况),那么问题来了,编译时会报大量的重复定义错误。

    例如要编写头文件test.h,在头文件开头写上两行:
    #ifndef _TEST_H
    #define _TEST_H //一般是文件名的大写
    头文件结尾写上一行:
    #endif
    这样一个工程文件里同时包含两个test.h时,就不会出现重定义的错误了。

    分析:
    当第一次包含test.h时,由于没有定义_TEST_H,条件为真,这样就会包含(执行)#ifndef _TEST_H和#endif之间的代码,当第二次包含test.h时前面一次已经定义了_TEST_H,条件为假,#ifndef _TEST_H和#endif之间的代码也就不会再次被包含,这样就避免了重定义了。

    8-9行 #include

    从系统目录开始搜索TargetConditionals.h和objc⁩/objc.h文件并把内容代码载入。打开源文件目录,发现系统目录是⁨iPhoneSimulator.sdk⁩ ▸ ⁨usr⁩ ▸ ⁨include⁩,刚好也是当前目录。

    #include和#import
    #import 确定一个文件只能被导入一次,在递归包含或相互包含中不会引起交叉编译,是#include的改良版。

    #import和@class
    #import 就是把被引用类的头文件走一遍,即把.h文件里的变量和方法包含进来一次,且仅一次,@class只是告诉编译器这是个类,不包含变量和方法,所以后者编译效率更高。
    如果你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,如A–>B, B–>C, C–>D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。而是用@class则不会。

    总结:

    1. 如果不是c/c++,尽量用#import。
    2. 能在实现文件中#import,就不在头文件中#import。
    3. 能在头文件中@class+实现文件中#import,就不在头文件中#import。

    11-17行 NSInteger

    LP64:是64位环境所使用的不同数据模型中的一,表示采用int32,long64(L),pointer64(P)这种模型的64位机。类似还有ILP64、LLP64。

    TARGET_OS_WIN32:Generated code will run under 32-bit Windows
    。这里我有个疑惑,代码还能在win32系统上跑?

    NS_BUILD_32_LIKE_64:是什么意思,不懂

    在苹果的api实现中,NSInteger是一个封装,它会识别当前操作系统的位数,64位返回long,其他返回int。若要考虑兼容,就不要用NSInteger,改用int和long。

    19-23行 常量宏定义

    宏定义了几个常量NSIntegerMax、NSIntegerMin、NSUIntegerMax、NSINTEGER_DEFINED

    25-33行 NS_DESIGNATED_INITIALIZER

    如果指定的初始化方法有参,就把他作为默认初始化方法。
    涉及两个知识点:NS_DESIGNATED_INITIALIZER和__attribute__

    相关文章

      网友评论

        本文标题:认识NSObjCRuntime.h

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