Objective-C 运行时

  1. 源码加中文注释
/*
* Copyright (c) 1999-2007 Apple Inc.  All Rights Reserved.
* 
* @APPLE_LICENSE_HEADER_START@
* 
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
* 
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
* 
* @APPLE_LICENSE_HEADER_END@
*/

/ *
* Copyright(C)1999-2007年苹果公司保留所有权利。
*
* apple_license_header_start @ @
*
* 该文件包含原始代码和/或修改的原始代码中定义的,并受苹果公共资源许可证版本2(“许可证”)。除许可证外,您不得使用此文件。请复印一份http://www.opensource.apple.com/apsl/许可证和在读它之前使用这个文件。
*
* 原代码和软件分发的许可证分布在'是'的基础上的,没有任何形式的保证,明示或暗示,苹果特此声明,所有这样的保证,包括但不限于任何保证的适销性,针对特定用途的适用性或非侵权,安静的享受。
* 请参阅许可证规定的特定语文权利和限制的许可证。
*
* apple_license_header_end @ @
* /

#ifndef _OBJC_RUNTIME_H
#define _OBJC_RUNTIME_H

#include <objc/objc.h>
#include <stdarg.h>
#include <stdint.h>
#include <stddef.h>
#include <Availability.h>
#include <TargetConditionals.h>

#if TARGET_OS_MAC
#include <sys/types.h>
#endif


/* Types */

#if !OBJC_TYPES_DEFINED

/// An opaque type that represents a method in a class definition.
//表示类定义中的方法的不透明类型。
typedef struct objc_method *Method;

/// An opaque type that represents an instance variable.
//表示实例变量的不透明类型。
typedef struct objc_ivar *Ivar;

/// An opaque type that represents a category.
//表示类别的不透明类型。
typedef struct objc_category *Category;

/// An opaque type that represents an Objective-C declared property.
///不透明的类型,表示一个Objective-C声明的属性。
typedef struct objc_property *objc_property_t;

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

#endif

#ifdef __OBJC__
@class Protocol;
#else
typedef struct objc_object Protocol;
#endif

/// Defines a method
struct objc_method_description {
    SEL _Nullable name;               /**< The name of the method */ 方法名称
    char * _Nullable types;           /**< The types of the method arguments */ 方法参数类型列表
};

/// Defines a property attribute
typedef struct {
    const char * _Nonnull name;           /**< The name of the attribute */ 属性名称
    const char * _Nonnull value;          /**< The value of the attribute (usually empty) */  属性值
} objc_property_attribute_t;


/* Functions */ 
// 方法

/* Working with Instances */ 
// 实例操作

/** 
 * Returns a copy of a given object.  返回给定对象的拷贝
 * 
 * @param obj An Objective-C object. 参数 obj  是一个Objective-C 对象
 * @param size The size of the object \e obj.  参数size obj对象的size
 * 
 * @return A copy of \e obj. 返回一个obj的拷贝
 */
OBJC_EXPORT id _Nullable object_copy(id _Nullable obj, size_t size)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;

/** 
 * Frees the memory occupied by a given object.   释放所给对象占用的内存
 * 
 * @param obj An Objective-C object. 参数 obj  是一个Objective-C 对象
 * 
 * @return nil  返回nil
 */
OBJC_EXPORT id _Nullable
object_dispose(id _Nullable obj)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;

/** 
 * Returns the class of an object. 返回一个对象所属的类
 * 
 * @param obj The object you want to inspect. 参数obj 你要检查的对象
 * 
 * @return The class object of which \e object is an instance,  
 *  or \c Nil if \e object is \c nil. 返回一个对象实例所属的类对象。或nil对象对应的Nil
 */
OBJC_EXPORT Class _Nullable
object_getClass(id _Nullable obj) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Sets the class of an object. 设置对象所属的类
 * 
 * @param obj The object to modify.  参数 obj 要修改的对象
 * @param cls A class object. 参数 cls 一个类对象
 * 
 * @return The previous value of \e object's class, or \c Nil if \e object is \c nil.  返回对象之前所属的类,或是nil对象对应的Nil
 */
OBJC_EXPORT Class _Nullable
object_setClass(id _Nullable obj, Class _Nonnull cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);


/** 
 * Returns whether an object is a class object. 发回一个对象是不是类对象
 * 
 * @param obj An Objective-C object. 参数obj Objective-C 对象
 * 
 * @return true if the object is a class or metaclass, false otherwise. 如果对象是类或是元类返回true,否则返回false
 */
OBJC_EXPORT BOOL
object_isClass(id _Nullable obj)
    OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0, 2.0);


/** 
 * Reads the value of an instance variable in an object.  读取对象中实例变量的值。
 * 
 * @param obj The object containing the instance variable whose value you want to read. 参数 obj  包含要读取其值的实例变量的对象。
 * @param ivar The Ivar describing the instance variable whose value you want to read. 参数 ivar 你想要读取的实例变量
 * 
 * @return The value of the instance variable specified by \e ivar, or \c nil if \e object is \c nil. 指定的实例变量的值 当对象为nil时返回nil
 * 
 * @note \c object_getIvar is faster than \c object_getInstanceVariable if the Ivar
 *  for the instance variable is already known. 如果实例变量已知的情况下,object_getIvar 比 object_getInstanceVariable 要快
 */
OBJC_EXPORT id _Nullable
object_getIvar(id _Nullable obj, Ivar _Nonnull ivar) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Sets the value of an instance variable in an object. 设置一个对象内实例变量的值
 * 
 * @param obj The object containing the instance variable whose value you want to set. 参数 obj 你要修改的实例变量所在的对象
 * @param ivar The Ivar describing the instance variable whose value you want to set. 参数 ivar 你要修改的实例变量描述
 * @param value The new value for the instance variable. 参数 value 实例变量的新值
 * 
 * @note Instance variables with known memory management (such as ARC strong and weak)
 *  use that memory management. Instance variables with unknown memory management 
 *  are assigned as if they were unsafe_unretained.  注意内存管理的实例变量(如ARC强和弱)使用内存管理。未知的内存管理实例变量被分配为如果他们unsafe_unretained。
 * @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar 
 *  for the instance variable is already known. 注意如果实例变量描述符已知 object_setIvar 比 object_setInstanceVariable 快
 */
OBJC_EXPORT void
object_setIvar(id _Nullable obj, Ivar _Nonnull ivar, id _Nullable value) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Sets the value of an instance variable in an object. 设置对象内部实例变量的值
 * 
 * @param obj The object containing the instance variable whose value you want to set. 参数 obj 你要修改的实例变量所在的对象
 * @param ivar The Ivar describing the instance variable whose value you want to set. 参数 ivar 你要修改的实例变量描述
 * @param value The new value for the instance variable.  参数 value 实例变量的新值
 * 
 * @note Instance variables with known memory management (such as ARC strong and weak)
 *  use that memory management. Instance variables with unknown memory management 
 *  are assigned as if they were strong. 注意内存管理的实例变量(如ARC强和弱)使用内存管理。带有未知内存管理的实例变量被赋值为强。
 * @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar
 *  for the instance variable is already known. 
 */
OBJC_EXPORT void
object_setIvarWithStrongDefault(id _Nullable obj, Ivar _Nonnull ivar,
                                id _Nullable value) 
    OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);

/** 
 * Changes the value of an instance variable of a class instance. 修改类对象的实例变量
 * 
 * @param obj A pointer to an instance of a class. Pass the object containing 
 *  the instance variable whose value you wish to modify. 参数 obj 指向类对象的指针,传递需要修改实例变量的对象
 * @param name A C string. Pass the name of the instance variable whose value you wish to modify.参数 name 一个C字符串,传递一个你要修改的实例变量
 * @param value The new value for the instance variable.  参数 value 实例变量的新值
 * 
 * @return A pointer to the \c Ivar data structure that defines the type and 
 *  name of the instance variable specified by \e name. 返回一个指定的实例变量 定义类型和名称 Ivar 数据结构指针
 *
 * @note Instance variables with known memory management (such as ARC strong and weak)
 *  use that memory management. Instance variables with unknown memory management 
 *  are assigned as if they were unsafe_unretained. 注意 如果实例变量具有已知的内存管理那么久应用内存管理操作,如果不知道内存管理就直接复制当做 unsafe_unretained
 */
OBJC_EXPORT Ivar _Nullable
object_setInstanceVariable(id _Nullable obj, const char * _Nonnull name,
                           void * _Nullable value)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;

/** 
 * Changes the value of an instance variable of a class instance. 修改类对象的实例变量的值
 * 
 * @param obj A pointer to an instance of a class. Pass the object containing 
 *  the instance variable whose value you wish to modify.
 * @param name A C string. Pass the name of the instance variable whose value you wish to modify.
 * @param value The new value for the instance variable.
 * 
 * @return A pointer to the \c Ivar data structure that defines the type and 
 *  name of the instance variable specified by \e name.
 *
 * @note Instance variables with known memory management (such as ARC strong and weak)
 *  use that memory management. Instance variables with unknown memory management 
 *  are assigned as if they were strong.
 */
OBJC_EXPORT Ivar _Nullable
object_setInstanceVariableWithStrongDefault(id _Nullable obj,
                                            const char * _Nonnull name,
                                            void * _Nullable value)
    OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0)
    OBJC_ARC_UNAVAILABLE;

/** 
 * Obtains the value of an instance variable of a class instance. 获取类对象实例变量的值
 * 
 * @param obj A pointer to an instance of a class. Pass the object containing
 *  the instance variable whose value you wish to obtain. 参数 obj 指向类对象的指针
 * @param name A C string. Pass the name of the instance variable whose value you wish to obtain. 参数 name 一个C字符串,你要修改的实例变量的名称
 * @param outValue On return, contains a pointer to the value of the instance variable. 参数 输出值 包含一个指向实例变量值得指针
 * 
 * @return A pointer to the \c Ivar data structure that defines the type and name of
 *  the instance variable specified by \e name. 返回一个指向指定实例变量的包含类型和名称的数据结构Ivar的指针
 */
OBJC_EXPORT Ivar _Nullable
object_getInstanceVariable(id _Nullable obj, const char * _Nonnull name,
                           void * _Nullable * _Nullable outValue)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;


/* Obtaining Class Definitions */ 获取类定义

/** 
 * Returns the class definition of a specified class. 返回指定类的定义
 * 
 * @param name The name of the class to look up. 参数 name,要查看的类的名称
 * 
 * @return The Class object for the named class, or \c nil 
 *  if the class is not registered with the Objective-C runtime.返回指定名称的类对象,如果在Objective-C运行时没有注册对应的类返回nil
 * 
 * @note \c objc_getClass is different from \c objc_lookUpClass in that if the class
 *  is not registered, \c objc_getClass calls the class handler callback and then checks
 *  a second time to see whether the class is registered. \c objc_lookUpClass does 
 *  not call the class handler callback.注意objc_getClass与objc_lookUpClass不同,因为如果该类未注册,objc_getClass将调用类处理函数回调,然后再次检查该类是否已注册。 objc_lookUpClass不调用类处理程序回调。
 * 
 * @warning Earlier implementations of this function (prior to OS X v10.0)
 *  terminate the program if the class does not exist. 警告此函数的早期实现(在OS X v10.0之前)会在程序不存在的情况下终止程序。
 */
OBJC_EXPORT Class _Nullable
objc_getClass(const char * _Nonnull name)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the metaclass definition of a specified class. 返回指定类的元类定义
 * 
 * @param name The name of the class to look up. 参数 name 查看的类名称
 * 
 * @return The \c Class object for the metaclass of the named class, or \c nil if the class
 *  is not registered with the Objective-C runtime. 返回对应名称元类对象。如果在Objective-C运行时没有注册返回nil
 * 
 * @note If the definition for the named class is not registered, this function calls the class handler
 *  callback and then checks a second time to see if the class is registered. However, every class
 *  definition must have a valid metaclass definition, and so the metaclass definition is always returned,
 *  whether it’s valid or not.note注意如果已命名类的定义未注册,则此函数会调用类处理函数回调,然后再次检查该类是否已注册。但是,每个类定义都必须有一个有效的元类定义,因此总是返回元类定义,无论它是否有效。
 */
OBJC_EXPORT Class _Nullable
objc_getMetaClass(const char * _Nonnull name)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the class definition of a specified class. 返回指定类的类定义
 * 
 * @param name The name of the class to look up. 参数 name 查看类的名称
 * 
 * @return The Class object for the named class, or \c nil if the class
 *  is not registered with the Objective-C runtime. 返回对应类名的类对象,如果没有在Objective-C运行时注册类名则返回nil
 * 
 * @note \c objc_getClass is different from this function in that if the class is not
 *  registered, \c objc_getClass calls the class handler callback and then checks a second
 *  time to see whether the class is registered. This function does not call the class handler callback.注意objc_getClass与此函数不同,因为如果该类未注册,则objc_getClass将调用类处理函数回调,然后再次检查该类是否已注册。此函数不调用类处理程序回调。
 */
OBJC_EXPORT Class _Nullable
objc_lookUpClass(const char * _Nonnull name)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the class definition of a specified class. 返回指定类的类定义
 * 
 * @param name The name of the class to look up. 参数 name 查看类的名称
 * 
 * @return The Class object for the named class. 返回对应类名的类对象
 * 
 * @note This function is the same as \c objc_getClass, but kills the process if the class is not found.该函数与\ objc_getClass相同,但如果未找到类,则会终止该进程。
 * @note This function is used by ZeroLink, where failing to find a class would be a compile-time link error without ZeroLink.  ZeroLink使用该函数,如果找不到类,则该函数将成为没有ZeroLink的编译时链接错误。
 */
OBJC_EXPORT Class _Nonnull
objc_getRequiredClass(const char * _Nonnull name)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Obtains the list of registered class definitions. 获取注册的类定义列表
 * 
 * @param buffer An array of \c Class values. On output, each \c Class value points to
 *  one class definition, up to either \e bufferCount or the total number of registered classes,
 *  whichever is less. You can pass \c NULL to obtain the total number of registered class
 *  definitions without actually retrieving any class definitions.Class值的数组。在输出上,每个Class值指向一个类定义,最多为bufferCount或注册类的总数,以较少者为准。您可以传递NULL来获取注册类定义的总数,而不实际检索任何类定义。
 * @param bufferCount An integer value. Pass the number of pointers for which you have allocated space
 *  in \e buffer. On return, this function fills in only this number of elements. If this number is less
 *  than the number of registered classes, this function returns an arbitrary subset of the registered classes.param bufferCount一个整数值。传递您在缓冲区中为其分配空间的指针数量。返回时,这个函数只填充这个元素。如果这个数字小于注册类的数量,这个函数返回注册类的任意子集。
 * 
 * @return An integer value indicating the total number of registered classes.返回一个整数值,表示注册类的总数。
 * 
 * @note The Objective-C runtime library automatically registers all the classes defined in your source code.
 *  You can create class definitions at runtime and register them with the \c objc_addClass function.注意Objective-C运行时库自动注册源代码中定义的所有类。您可以在运行时创建类定义,并使用objc_addClass函数注册它们。
 * 
 * @warning You cannot assume that class objects you get from this function are classes that inherit from \c NSObject,
 *  so you cannot safely call any methods on such classes without detecting that the method is implemented first.   警告你不能认为你从这个函数中得到的类对象是继承自NSObject的类,所以你不能安全地调用这些类的任何方法,而没有检测到该方法首先被实现。
 */
OBJC_EXPORT int
objc_getClassList(Class _Nonnull * _Nullable buffer, int bufferCount)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Creates and returns a list of pointers to all registered class definitions.创建并返回指向所有注册类定义的指针列表
 * 
 * @param outCount An integer pointer used to store the number of classes returned by
 *  this function in the list. It can be \c nil.  参数 outCount一个整数指针,用于存储此函数在列表中返回的类的数量。 它可以是nil。
 * 
 * @return A nil terminated array of classes. It must be freed with \c free(). 返回一个以nil结尾的类数组,它必须用free()释放
 * 
 * @see objc_getClassList
 */
OBJC_EXPORT Class _Nonnull * _Nullable
objc_copyClassList(unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.7, 3.1, 9.0, 1.0, 2.0);


/* Working with Classes */ 类操作

/** 
 * Returns the name of a class. 返回类名称
 * 
 * @param cls A class object. 参数 cls 类对象
 * 
 * @return The name of the class, or the empty string if \e cls is \c Nil. 返回类的名称,如果cls 是Nil则返回空字符串
 */
OBJC_EXPORT const char * _Nonnull
class_getName(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a Boolean value that indicates whether a class object is a metaclass.返回一个表示一个类是不是元类的布尔值
 * 
 * @param cls A class object. 参数 cls 一个类对象
 * 
 * @return \c YES if \e cls is a metaclass, \c NO if \e cls is a non-meta class, 
 *  \c NO if \e cls is \c Nil. 如果cls是元类发回YES,如果cls是一个非元类返回NO,如果cls是Nil返回NO
 */
OBJC_EXPORT BOOL
class_isMetaClass(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the superclass of a class. 返回一个类的父类
 * 
 * @param cls A class object. 参数cls一个类对象
 * 
 * @return The superclass of the class, or \c Nil if
 *  \e cls is a root class, or \c Nil if \e cls is \c Nil. 返回类的父类,如果cls是根类返回Nil,如果cls是Nil返回Nil
 *
 * @note You should usually use \c NSObject's \c superclass method instead of this function. 注意通常应该使用NSObject的superclass方法而不是这个函数
 */
OBJC_EXPORT Class _Nullable
class_getSuperclass(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Sets the superclass of a given class. 设置给定类的父类
 * 
 * @param cls The class whose superclass you want to set. 参数 cls 你要修改父类的类
 * @param newSuper The new superclass for cls. 参数 newSuper 新的父类
 * 
 * @return The old superclass for cls. 返回cls的老的父类
 * 
 * @warning You should not use this function. 警告 你不应该使用这个方法
 */
OBJC_EXPORT Class _Nonnull
class_setSuperclass(Class _Nonnull cls, Class _Nonnull newSuper) 
    __OSX_DEPRECATED(10.5, 10.5, "not recommended") 
    __IOS_DEPRECATED(2.0, 2.0, "not recommended") 
    __TVOS_DEPRECATED(9.0, 9.0, "not recommended") 
    __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended")
    __BRIDGEOS_DEPRECATED(2.0, 2.0, "not recommended");

/** 
 * Returns the version number of a class definition. 返回类定义的版本号
 * 
 * @param cls A pointer to a \c Class data structure. Pass
 *  the class definition for which you wish to obtain the version. 参数 cls 一个指向类数据结构的指针,传递一个你想要获取版本的类定义
 * 
 * @return An integer indicating the version number of the class definition. 返回一个表示类定义的版本号的整数
 *
 * @see class_setVersion
 */
OBJC_EXPORT int
class_getVersion(Class _Nullable cls)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Sets the version number of a class definition. 设置类定义的版本号
 * 
 * @param cls A pointer to an Class data structure. 
 *  Pass the class definition for which you wish to set the version. 参数cls,一个指向类数据结构的指针,传递一个你想要修改版本的类定义
 * @param version An integer. Pass the new version number of the class definition. 参数version 一个整数。传递一个新的类定义的版本号
 *
 * @note You can use the version number of the class definition to provide versioning of the
 *  interface that your class represents to other classes. This is especially useful for object
 *  serialization (that is, archiving of the object in a flattened form), where it is important to
 *  recognize changes to the layout of the instance variables in different class-definition versions.    注意您可以使用类定义的版本号来为您的类表示的接口提供版本控制给其他类。 这对于对象序列化(也就是说,以扁平形式对对象进行归档)尤其有用,其中识别对不同类定义版本中实例变量的布局所做的更改很重要。
 * @note Classes derived from the Foundation framework \c NSObject class can set the class-definition
 *  version number using the \c setVersion: class method, which is implemented using the \c class_setVersion function.    注意从Foundation框架派生的类NSObject类可以使用setVersion:class方法设置类定义版本号,该方法使用class_setVersion函数实现。
 */
OBJC_EXPORT void
class_setVersion(Class _Nullable cls, int version)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the size of instances of a class.返回类的实例的大小
 * 
 * @param cls A class object. 参数cls一个雷对象
 * 
 * @return The size in bytes of instances of the class \e cls, or \c 0 if \e cls is \c Nil.
 */返回cls类的实例的字节大小,如果cls是Nil返回0
OBJC_EXPORT size_t
class_getInstanceSize(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the \c Ivar for a specified instance variable of a given class. 返回给定类的指定实例变量的Ivar。
 * 
 * @param cls The class whose instance variable you wish to obtain. 参数 cls 你想要获取实例变量的类
 * @param name The name of the instance variable definition to obtain. 参数name 你想要获取实例变量的名称
 * 
 * @return A pointer to an \c Ivar data structure containing information about 
 *  the instance variable specified by \e name.返回一个指向包含指定名称的实例变量的Ivar数据结构的指针
 */
OBJC_EXPORT Ivar _Nullable
class_getInstanceVariable(Class _Nullable cls, const char * _Nonnull name)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the Ivar for a specified class variable of a given class. 返回给定类的指定类变量的Ivar。
 * 
 * @param cls The class definition whose class variable you wish to obtain. 参数 cls 你要修改的类变量所在的类定义
 * @param name The name of the class variable definition to obtain. 参数名称 类变量的名称
 * 
 * @return A pointer to an \c Ivar data structure containing information about the class variable specified by \e name.
 */
OBJC_EXPORT Ivar _Nullable
class_getClassVariable(Class _Nullable cls, const char * _Nonnull name) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Describes the instance variables declared by a class.  描述由类声明的实例变量。
 * 
 * @param cls The class to inspect.   参数 cls  要检查的类
 * @param outCount On return, contains the length of the returned array. 
 *  If outCount is NULL, the length is not returned. 参数 outCount返回时,包含返回数组的长度。 如果outCount为NULL,则不返回长度。
 * 
 * @return An array of pointers of type Ivar describing the instance variables declared by the class. 
 *  Any instance variables declared by superclasses are not included. The array contains *outCount 
 *  pointers followed by a NULL terminator. You must free the array with free().  返回一个Ivar类型的指针数组,用于描述该类声明的实例变量。 不包括由超类声明的任何实例变量。 该数组包含* outCount指针,后跟NULL结束符。 你必须用free()释放数组。
 * 
 *  If the class declares no instance variables, or cls is Nil, NULL is returned and *outCount is 0.  如果类没有声明实例变量,或cls是Nil,会返回NULL并且*outCount是0
 */
OBJC_EXPORT Ivar _Nonnull * _Nullable
class_copyIvarList(Class _Nullable cls, unsigned int * _Nullable outCount) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a specified instance method for a given class. 返回给定类的指定的实例方法
 * 
 * @param cls The class you want to inspect. 参数cls你要检查的类
 * @param name The selector of the method you want to retrieve. 参数name您要检索的方法的选择器。
 * 
 * @return The method that corresponds to the implementation of the selector specified by 
 *  \e name for the class specified by \e cls, or \c NULL if the specified class or its 
 *  superclasses do not contain an instance method with the specified selector.  返回与由cls指定的类的名称指定的选择器的实现对应的方法,如果指定的类或其超类不包含具有指定选择器的实例方法,则为NULL。
 *
 * @note This function searches superclasses for implementations, whereas \c class_copyMethodList does not.注意此函数搜索父类实现,而class_copyMethodList不会。
 */
OBJC_EXPORT Method _Nullable
class_getInstanceMethod(Class _Nullable cls, SEL _Nonnull name)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a pointer to the data structure describing a given class method for a given class. 返回一个指向给定类的给定类方法的数据结构描述的指针
 * 
 * @param cls A pointer to a class definition. Pass the class that contains the method you want to retrieve. 参数 cls 一个指向类定义的指针。传递一个你想要查看方法的类
 * @param name A pointer of type \c SEL. Pass the selector of the method you want to retrieve. 参数 name 一个指向SEL类型的指针。传递你想要获取的方法选择器
 * 
 * @return A pointer to the \c Method data structure that corresponds to the implementation of the 
 *  selector specified by aSelector for the class specified by aClass, or NULL if the specified  
 *  class or its superclasses do not contain an instance method with the specified selector.  返回指向Method数据结构的指针,该指针对应于由aClass指定的类由aSelector指定的选择器的实现;如果指定的类或其超类不包含具有指定选择器的实例方法,则为NULL。
 *
 * @note Note that this function searches superclasses for implementations, 
 *  whereas \c class_copyMethodList does not. 注意这个函数会搜索父类实现,而class_copyMethodList 不会
 */
OBJC_EXPORT Method _Nullable
class_getClassMethod(Class _Nullable cls, SEL _Nonnull name)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the function pointer that would be called if a 
 * particular message were sent to an instance of a class. 返回在特定消息发送到类的实例时将被调用的函数指针。
 * 
 * @param cls The class you want to inspect. 参数 cls 你要检查的类
 * @param name A selector.
 * 
 * @return The function pointer that would be called if \c [object name] were called
 *  with an instance of the class, or \c NULL if \e cls is \c Nil. 如果[object name]是用类的实例调用的返回函数指针,如果cls为Nil,则为NULL。
 *
 * @note \c class_getMethodImplementation may be faster than \c method_getImplementation(class_getInstanceMethod(cls, name)). 注意class_getMethodImplementation可能会比method_getImplementation(class_getInstanceMethod(cls,name))快
 * @note The function pointer returned may be a function internal to the runtime instead of
 *  an actual method implementation. For example, if instances of the class do not respond to
 *  the selector, the function pointer returned will be part of the runtime's message forwarding machinery.  注意返回的函数指针可能是运行时内部的函数,而不是实际的方法实现。 例如,如果类的实例没有响应选择器,则返回的函数指针将成为运行时的消息转发机制的一部分。
 */
OBJC_EXPORT IMP _Nullable
class_getMethodImplementation(Class _Nullable cls, SEL _Nonnull name) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the function pointer that would be called if a particular 
 * message were sent to an instance of a class.  返回在特定消息发送到类的实例时将被调用的函数指针。
 * 
 * @param cls The class you want to inspect. 参数 cls 你要检查的类
 * @param name A selector. 参数名称 一个方法选择器
 * 
 * @return The function pointer that would be called if \c [object name] were called
 *  with an instance of the class, or \c NULL if \e cls is \c Nil. 返回如果使用类的实例调用[object name]时将调用的函数指针,如果cls为Nil,则返回NULL。
 */
OBJC_EXPORT IMP _Nullable
class_getMethodImplementation_stret(Class _Nullable cls, SEL _Nonnull name) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0)
    OBJC_ARM64_UNAVAILABLE;

/** 
 * Returns a Boolean value that indicates whether instances of a class respond to a particular selector. 返回布尔值表示这个类的实例是否响应特定方法选择器
 * 
 * @param cls The class you want to inspect. 参数 cls 你要检查的类
 * @param sel A selector. 参数 sel 一个选择器
 * 
 * @return \c YES if instances of the class respond to the selector, otherwise \c NO. 如果类的实例响应这个方法返回yes,否则返回NO
 * 
 * @note You should usually use \c NSObject's \c respondsToSelector: or \c instancesRespondToSelector: 
 *  methods instead of this function. 注意你应该使用NSObject的respondsToSelector:或是instancesRespondToSelector:而不是这个函数
 */
OBJC_EXPORT BOOL
class_respondsToSelector(Class _Nullable cls, SEL _Nonnull sel) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Describes the instance methods implemented by a class. 描述实例方法是由类实现的
 * 
 * @param cls The class you want to inspect. 参数cls 你要检查的类
 * @param outCount On return, contains the length of the returned array. 
 *  If outCount is NULL, the length is not returned.参数outCount,如果返回,里面包含了数组的长度,如果cou
 * 
 * @return An array of pointers of type Method describing the instance methods 
 *  implemented by the class—any instance methods implemented by superclasses are not included. 
 *  The array contains *outCount pointers followed by a NULL terminator. You must free the array with free().  描述由类实现的实例方法的类型为Method的指针数组 - 任何由超类实现的实例方法都不包含在内。 该数组包含* outCount指针,后跟NULL结束符。 你必须用free()释放数组。
 * 
 *  If cls implements no instance methods, or cls is Nil, returns NULL and *outCount is 0.

如果cls不实现实例方法,或者cls为Nil,则返回NULL并且* outCount为0。
*
* @note To get the class methods of a class, use \c class_copyMethodList(object_getClass(cls), &count).
* @note To get the implementations of methods that may be implemented by superclasses,
* use \c class_getInstanceMethod or \c class_getClassMethod. note注意要获取可能由超类实现的方法的实现,请使用\ c class_getInstanceMethod或\ c class_getClassMethod。
*/
OBJC_EXPORT Method _Nonnull * _Nullable
class_copyMethodList(Class _Nullable cls, unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a Boolean value that indicates whether a class conforms to a given protocol.   返回一个表示一个类是否遵守给定协议的布尔值
 * 
 * @param cls The class you want to inspect. 参数cls 一个你要检查的类
 * @param protocol A protocol. 参数 protocol 一个协议
 *
 * @return YES if cls conforms to protocol, otherwise NO. 如果遵守了协议返回YES,否则返回NO
 *
 * @note You should usually use NSObject's conformsToProtocol: method instead of this function.  注意你应该使用NSObject的conformsToProtocol:方法而不是这个函数
 */
OBJC_EXPORT BOOL
class_conformsToProtocol(Class _Nullable cls, Protocol * _Nullable protocol) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Describes the protocols adopted by a class. 描述一个类所遵守的协议
 * 
 * @param cls The class you want to inspect. 参数 cls 一个你要检查的类
 * @param outCount On return, contains the length of the returned array. 
 *  If outCount is NULL, the length is not returned.  参数outCount,在返回的情况下包含返回数组的长度,如果outCount是NULL,长度没有返回
 *  
 * @return An array of pointers of type Protocol* describing the protocols adopted 
 *  by the class. Any protocols adopted by superclasses or other protocols are not included. 
 *  The array contains *outCount pointers followed by a NULL terminator. You must free the array with free().  返回一个类型为Protocol *的指针数组,用于描述该类所遵守的协议。 不包括由超类或其他协议遵守的任何协议。 该数组包含* outCount指针,后跟NULL结束符。 你必须用free()释放数组。
 * 
 *  If cls adopts no protocols, or cls is Nil, returns NULL and *outCount is 0. 如果cls 没有遵守任何协议,回事cls是Nil,返回NULL并且*outCount是0
 */
OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable 
class_copyProtocolList(Class _Nullable cls, unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a property with a given name of a given class. 返回一个指定类指定名称的属性
 * 
 * @param cls The class you want to inspect. 参数 cls 你要检查的类
 * @param name The name of the property you want to inspect. 参数name,你要检查的属性的名称
 * 
 * @return A pointer of type \c objc_property_t describing the property, or
 *  \c NULL if the class does not declare a property with that name, 
 *  or \c NULL if \e cls is \c Nil. 返回一个描述属性的 objc_property_t 类型的指针,如果没有声明这个属性返回NULL,如果cls是Nil返回NULL
 */
OBJC_EXPORT objc_property_t _Nullable
class_getProperty(Class _Nullable cls, const char * _Nonnull name)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Describes the properties declared by a class. 描述类声明的属性
 * 
 * @param cls The class you want to inspect. 参数 cls 你要检查的类
 * @param outCount On return, contains the length of the returned array. 
 *  If \e outCount is \c NULL, the length is not returned.        
 * 
 * @return An array of pointers of type \c objc_property_t describing the properties 
 *  declared by the class. Any properties declared by superclasses are not included. 
 *  The array contains \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free().  返回一个类型为objc_property_t的指针数组,用于描述该类声明的属性。 不包括由超类声明的任何属性。 该数组包含* outCount指针,后跟NULL结束符。 你必须用free()释放数组。
 * 
 *  If \e cls declares no properties, or \e cls is \c Nil, returns \c NULL and \c *outCount is \c 0.  如果 cls 没有声明任何属性,或是cls是Nil,返回NUll并且*outCount是0
 */
OBJC_EXPORT objc_property_t _Nonnull * _Nullable
class_copyPropertyList(Class _Nullable cls, unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a description of the \c Ivar layout for a given class. 返回一个给定类的Ivar
 * 
 * @param cls The class to inspect. 参数cls 你要检查的类
 * 
 * @return A description of the \c Ivar layout for \e cls. 
 */
OBJC_EXPORT const uint8_t * _Nullable
class_getIvarLayout(Class _Nullable cls)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a description of the layout of weak Ivars for a given class.  返回给定类的弱Ivars布局的描述。
 * 
 * @param cls The class to inspect. 
 * 
 * @return A description of the layout of the weak \c Ivars for \e cls.
 */
OBJC_EXPORT const uint8_t * _Nullable
class_getWeakIvarLayout(Class _Nullable cls)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Adds a new method to a class with a given name and implementation. 向具有给定名称和实现的类添加新方法。
 * 
 * @param cls The class to which to add a method. 参数 cls 要添加方法的类
 * @param name A selector that specifies the name of the method being added.   参数 name 一个选择器指向指定名称的方法
 * @param imp A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd. 参数imp 一个实现了新方法的函数,这个函数必须至少有两个参数self和_cmd
 * @param types An array of characters that describe the types of the arguments to the method. 参数types 一个表示方法参数类型的字符数组
 * 
 * @return YES if the method was added successfully, otherwise NO  如果这个方法添加成功返回YES,否则返回NO
 *  (for example, the class already contains a method implementation with that name).
 *
 * @note class_addMethod will add an override of a superclass's implementation, 
 *  but will not replace an existing implementation in this class. 
 *  To change an existing implementation, use method_setImplementation.  注释class_addMethod将添加超类实现的重写,但不会替换此类中的现有实现。 要更改现有的实现,请使用method_setImplementation。
 */
OBJC_EXPORT BOOL
class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, 
                const char * _Nullable types) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Replaces the implementation of a method for a given class. 替换一个给定类的方法实现
 * 
 * @param cls The class you want to modify. 你要处理的类
 * @param name A selector that identifies the method whose implementation you want to replace. 参数name 一个选择器你要替换它的实现
 * @param imp The new implementation for the method identified by name for the class identified by cls. 参数 imp  一个新的由cls确定的类的由name确定的方法的实现
 * @param types An array of characters that describe the types of the arguments to the method. 
 *  Since the function must take at least two arguments—self and _cmd, the second and third characters
 *  must be “@:” (the first character is the return type). 参数类型描述方法参数类型的字符数组。 由于函数至少需要两个参数self和_cmd,所以第二个和第三个字符必须是“@:”(第一个字符是返回类型)。
 * 
 * @return The previous implementation of the method identified by \e name for the class identified by \e cls.  返回由cls标识的类的名称标识的方法的先前实现。
 * 
 * @note This function behaves in two different ways:
 *  - If the method identified by \e name does not yet exist, it is added as if \c class_addMethod were called. 
 *    The type encoding specified by \e types is used as given.
 *  - If the method identified by \e name does exist, its \c IMP is replaced as if \c method_setImplementation were called.
 *    The type encoding specified by \e types is ignored. 该函数的行为有两种不同的方式:如果名称标识的方法尚不存在,则按照调用class_addMethod的方式添加该方法。type指定的类型编码用作given。如果名称标识的方法存在,则其IMP 被替换,就好像调用了method_setImplementation。忽略了由类型指定的类型编码。
 */
OBJC_EXPORT IMP _Nullable
class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, 
                    const char * _Nullable types) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Adds a new instance variable to a class.  添加新示例变量到一个类
 * 
 * @return YES if the instance variable was added successfully, otherwise NO 
 *         (for example, the class already contains an instance variable with that name).  如果实例变量已成功添加,则返回YES,否则返回NO(例如,该类已包含具有该名称的实例变量)。
 *
 * @note This function may only be called after objc_allocateClassPair and before objc_registerClassPair.  
 *       Adding an instance variable to an existing class is not supported. 注意这个函数只能在objc_allocateClassPair之后并且objc_registerClassPair之前被调用,添加实例变量到一个已存在的类是不支持的
 * @note The class must not be a metaclass. Adding an instance variable to a metaclass is not supported. 这个类不能是元类。添加一个实例变量到一个元类是不支持的。
 * @note The instance variable's minimum alignment in bytes is 1<<align. The minimum alignment of an instance 
 *       variable depends on the ivar's type and the machine architecture. 
 *       For variables of any pointer type, pass log2(sizeof(pointer_type)).实例变量的最小对齐字节数为1 << align。 实例变量的最小对齐取决于伊娃的类型和机器体系结构。 对于任何指针类型的变量,传递log2(sizeof(pointer_type))。
 */
OBJC_EXPORT BOOL
class_addIvar(Class _Nullable cls, const char * _Nonnull name, size_t size, 
              uint8_t alignment, const char * _Nullable types) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Adds a protocol to a class.添加一个协议到一个类
 * 
 * @param cls The class to modify. cls 修改的类
 * @param protocol The protocol to add to \e cls. 参数 protocol 要添加到cls的协议
 * 
 * @return \c YES if the method was added successfully, otherwise \c NO 
 *  (for example, the class already conforms to that protocol). 如果添加成功返回YES,否则返回NO
 */
OBJC_EXPORT BOOL
class_addProtocol(Class _Nullable cls, Protocol * _Nonnull protocol) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Adds a property to a class. 对类添加属性
 * 
 * @param cls The class to modify. 参数 cls 要修改的类
 * @param name The name of the property. 参数 name 属性的名称
 * @param attributes An array of property attributes. 参数 attributes 一个属性特性数组
 * @param attributeCount The number of attributes in \e attributes. 参数 attributeCount 特性数量
 * 
 * @return \c YES if the property was added successfully, otherwise \c NO
 *  (for example, the class already has that property). 如果属性添加成功返回YES,否则返回NO
 */
OBJC_EXPORT BOOL
class_addProperty(Class _Nullable cls, const char * _Nonnull name,
                  const objc_property_attribute_t * _Nullable attributes,
                  unsigned int attributeCount)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Replace a property of a class.  替换一个类的属性
 * 
 * @param cls The class to modify. 参数 cls 要修改的类
 * @param name The name of the property. 参数 name 属性名称
 * @param attributes An array of property attributes. 参数 attributes 一个属性特性数组
 * @param attributeCount The number of attributes in \e attributes.  参数 attributeCount 特性数量
 */
OBJC_EXPORT void
class_replaceProperty(Class _Nullable cls, const char * _Nonnull name,
                      const objc_property_attribute_t * _Nullable attributes,
                      unsigned int attributeCount)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Sets the Ivar layout for a given class.   为给定的类设置Ivar布局。
 * 
 * @param cls The class to modify. 参数 cls 要修改的类
 * @param layout The layout of the \c Ivars for \e cls. 参数 layout cls的Ivars的分布
 */ 
OBJC_EXPORT void
class_setIvarLayout(Class _Nullable cls, const uint8_t * _Nullable layout)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Sets the layout for weak Ivars for a given class. 这个与上一个很相似,只不过是weak修饰的Ivar
 * 
 * @param cls The class to modify.
 * @param layout The layout of the weak Ivars for \e cls.
 */
OBJC_EXPORT void
class_setWeakIvarLayout(Class _Nullable cls, const uint8_t * _Nullable layout)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Used by CoreFoundation's toll-free bridging.
 * Return the id of the named class.
 * 
 * @return The id of the named class, or an uninitialized class
 *  structure that will be used for the class when and if it does 
 *  get loaded. 已命名类的id或未初始化的类结构,将在类加载时用于该类。
 * 
 * @warning Do not call this function yourself. 注意你不要调用这个函数
 */
OBJC_EXPORT Class _Nonnull
objc_getFutureClass(const char * _Nonnull name) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;


/* Instantiating Classes */ 实例化类

/** 
 * Creates an instance of a class, allocating memory for the class in the 
 * default malloc memory zone.   创建一个类的实例,为默认的malloc内存区域中的类分配内存。
 * 
 * @param cls The class that you wish to allocate an instance of.
 * @param extraBytes An integer indicating the number of extra bytes to allocate. 
 *  The additional bytes can be used to store additional instance variables beyond 
 *  those defined in the class definition.  param extraBytes一个整数,指示要分配的额外字节数。 附加字节可用于存储除类定义中定义的其他实例变量外的其他实例变量。
 * 
 * @return An instance of the class \e cls. 返回cls 的实例
 */
OBJC_EXPORT id _Nullable
class_createInstance(Class _Nullable cls, size_t extraBytes)
    OBJC_RETURNS_RETAINED
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Creates an instance of a class at the specific location provided. 在已提供的位置建立一个类的实例
 * 
 * @param cls The class that you wish to allocate an instance of. 参数cls,你想初始化实例的类
 * @param bytes The location at which to allocate an instance of \e cls.
 *  Must point to at least \c class_getInstanceSize(cls) bytes of well-aligned,
 *  zero-filled memory.  分配cls实例的位置必须指向至少class_getInstanceSize(cls)字节的良好对齐的零填充内存。
 *
 * @return \e bytes on success, \c nil otherwise. (For example, \e cls or \e bytes
 *  might be \c nil) 如果成功返回bytes,否则返回nil
 *
 * @see class_createInstance
 */
OBJC_EXPORT id _Nullable
objc_constructInstance(Class _Nullable cls, void * _Nullable bytes) 
    OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;

/** 
 * Destroys an instance of a class without freeing memory and removes any
 * associated references this instance might have had. 在不释放内存的情况下销毁类的实例,并删除此实例可能具有的任何关联引用。
 * 
 * @param obj The class instance to destroy. 参数 obj 要销毁的类实例
 * 
 * @return \e obj. Does nothing if \e obj is nil. 返回 obj 如果obj 是nil
 * 
 * @note CF and other clients do call this under GC. 
 */
OBJC_EXPORT void * _Nullable objc_destructInstance(id _Nullable obj) 
    OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;


/* Adding Classes */ 添加类

/** 
 * Creates a new class and metaclass. 创建新类
 * 
 * @param superclass The class to use as the new class's superclass, or \c Nil to create a new root class. 参数 superclass 用来创建类的父类,如果是Nil就创建一个根类
 * @param name The string to use as the new class's name. The string will be copied. 参数name 新类的名称,这个字符串会被拷贝走
 * @param extraBytes The number of bytes to allocate for indexed ivars at the end of 
 *  the class and metaclass objects. This should usually be \c 0.  在类和元类对象末尾为索引的ivars分配的字节数。 这通常应该是0。
 * 
 * @return The new class, or Nil if the class could not be created (for example, the desired name is already in use). 返回新类,如果不能创建就返回Nil(比如 期望的类名已经被占用)
 * 
 * @note You can get a pointer to the new metaclass by calling \c object_getClass(newClass). 注意 你可以通过object_getClass(newClass)获得指向新的元类的指针
 * @note To create a new class, start by calling \c objc_allocateClassPair.  
 *  Then set the class's attributes with functions like \c class_addMethod and \c class_addIvar.
 *  When you are done building the class, call \c objc_registerClassPair. The new class is now ready for use.  注意要创建一个新类,请首先调用objc_allocateClassPair。 然后使用class_addMethod和class_addIvar等函数设置类的属性。 完成构建类后,请调用objc_registerClassPair。 新类就可以使用了。
 * @note Instance methods and instance variables should be added to the class itself. 
 *  Class methods should be added to the metaclass. 实例方法和实例变量应该被添加到类本身。 类方法应该添加到元类中。
 */
OBJC_EXPORT Class _Nullable
objc_allocateClassPair(Class _Nullable superclass, const char * _Nonnull name, 
                       size_t extraBytes) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Registers a class that was allocated using \c objc_allocateClassPair. 注册是个已经被用objc_allocateClassPair 创建的类
 * 
 * @param cls The class you want to register. 参数cls 你要注册的类
 */
OBJC_EXPORT void
objc_registerClassPair(Class _Nonnull cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Used by Foundation's Key-Value Observing. 使用Foundation的键值监听
 * 
 * @warning Do not call this function yourself.  注意不用自己调用这个函数
 */
OBJC_EXPORT Class _Nonnull
objc_duplicateClass(Class _Nonnull original, const char * _Nonnull name,
                    size_t extraBytes)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Destroy a class and its associated metaclass.  销毁一个类和它相关元类
 * 
 * @param cls The class to be destroyed. It must have been allocated with 
 *  \c objc_allocateClassPair 参数 cls,要被销毁的类。它必须是通过objc_allocateClassPair创建的
 * 
 * @warning Do not call if instances of this class or a subclass exist.不要在有子类存在的情况下调用这个函数
 */
OBJC_EXPORT void
objc_disposeClassPair(Class _Nonnull cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);


/* Working with Methods */ 操作方法

/** 
 * Returns the name of a method. 获取方法的名称
 * 
 * @param m The method to inspect. 参数m 要检查的方法
 *  
 * @return A pointer of type SEL. 返回一个SEL的指针
 * 
 * @note To get the method name as a C string, call \c sel_getName(method_getName(method)). 如果要获取C字符串的名称,请使用sel_getName(method_getName(method))
 */
OBJC_EXPORT SEL _Nonnull
method_getName(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the implementation of a method. 返回方法实现
 * 
 * @param m The method to inspect. 参数m 要检查的方法
 * 
 * @return A function pointer of type IMP. 返回一个IMP类型的函数指针
 */
OBJC_EXPORT IMP _Nonnull
method_getImplementation(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a string describing a method's parameter and return types. 返回一个描述方法参数类型和返回类型的字符串
 * 
 * @param m The method to inspect. 参数m要检查的方法
 * 
 * @return A C string. The string may be \c NULL. 返回一个C字符串,也可能是NULL
 */
OBJC_EXPORT const char * _Nullable
method_getTypeEncoding(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the number of arguments accepted by a method. 返回方法参数的数量
 * 
 * @param m A pointer to a \c Method data structure. Pass the method in question. 参数m 一个指向方法数据结构的指针。传递一个方法
 * 
 * @return An integer containing the number of arguments accepted by the given method.
 */ 返回给定方法接收参数的数量,是一个整数
OBJC_EXPORT unsigned int
method_getNumberOfArguments(Method _Nonnull m)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a string describing a method's return type. 返回一个描述方法返回值类型的字符串
 * 
 * @param m The method to inspect. 参数m 要检查的方法
 * 
 * @return A C string describing the return type. You must free the string with \c free().
 */ 返回一个描述返回值类型的C字符串,你必须用free()函数释放内存
OBJC_EXPORT char * _Nonnull
method_copyReturnType(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a string describing a single parameter type of a method. 返回描述方法的单个参数类型的字符串。
 * 
 * @param m The method to inspect. 参数m用检查的方法
 * @param index The index of the parameter to inspect. 参数 index 要检查参数的位置
 * 
 * @return A C string describing the type of the parameter at index \e index, or \c NULL
 *  if method has no parameter index \e index. You must free the string with \c free().  返回描述索引索引处参数类型的C字符串,如果方法没有参数索引索引,则返回NULL。 你必须用free()释放字符串。
 */
OBJC_EXPORT char * _Nullable
method_copyArgumentType(Method _Nonnull m, unsigned int index) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns by reference a string describing a method's return type. 通过引用返回描述方法返回类型的字符串。
 * 
 * @param m The method you want to inquire about. 
 * @param dst The reference string to store the description.
 * @param dst_len The maximum number of characters that can be stored in \e dst.
 *
 * @note The method's return type string is copied to \e dst.
 *  \e dst is filled as if \c strncpy(dst, parameter_type, dst_len) were called.  该方法的返回类型字符串被复制到dst。 dst被填充,就好像strncpy(dst,parameter_type,dst_len)被调用。
 */
OBJC_EXPORT void
method_getReturnType(Method _Nonnull m, char * _Nonnull dst, size_t dst_len) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns by reference a string describing a single parameter type of a method.  通过引用返回描述方法的单个参数类型的字符串。
 * 
 * @param m The method you want to inquire about. 
 * @param index The index of the parameter you want to inquire about.
 * @param dst The reference string to store the description.
 * @param dst_len The maximum number of characters that can be stored in \e dst.
 * 
 * @note The parameter type string is copied to \e dst. \e dst is filled as if \c strncpy(dst, parameter_type, dst_len) 
 *  were called. If the method contains no parameter with that index, \e dst is filled as
 *  if \c strncpy(dst, "", dst_len) were called.  参数类型字符串被复制到dst。 dst被填充,就好像strncpy(dst,parameter_type,dst_len)被调用。 如果该方法不包含具有该索引的参数,则会调用dst,就像调用strncpy(dst,“”,dst_len)一样。
 */
OBJC_EXPORT void
method_getArgumentType(Method _Nonnull m, unsigned int index, 
                       char * _Nullable dst, size_t dst_len) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

OBJC_EXPORT struct objc_method_description * _Nonnull
method_getDescription(Method _Nonnull m) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Sets the implementation of a method. 设置方法的实现
 * 
 * @param m The method for which to set an implementation. 
 * @param imp The implemention to set to this method.
 * 
 * @return The previous implementation of the method. 返回之前的实现
 */
OBJC_EXPORT IMP _Nonnull
method_setImplementation(Method _Nonnull m, IMP _Nonnull imp) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Exchanges the implementations of two methods. 交换两个方法的实现
 * 
 * @param m1 Method to exchange with second method.
 * @param m2 Method to exchange with first method.
 * 
 * @note This is an atomic version of the following: 以下的原子版本:
 *  \code 
 *  IMP imp1 = method_getImplementation(m1);
 *  IMP imp2 = method_getImplementation(m2);
 *  method_setImplementation(m1, imp2);
 *  method_setImplementation(m2, imp1);
 *  \endcode
 */
OBJC_EXPORT void
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);


/* Working with Instance Variables */ 操作实例变量

/** 
 * Returns the name of an instance variable. 返回实例变量的名称
 * 
 * @param v The instance variable you want to enquire about. 
 * 
 * @return A C string containing the instance variable's name.
 */
OBJC_EXPORT const char * _Nullable
ivar_getName(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the type string of an instance variable. 返回实例变量的类型字符串
 * 
 * @param v The instance variable you want to enquire about.
 * 
 * @return A C string containing the instance variable's type encoding.
 *
 * @note For possible values, see Objective-C Runtime Programming Guide > Type Encodings. 可能的值,请参阅“Objective-C运行时编程指南”>“类型编码”。
 */
OBJC_EXPORT const char * _Nullable
ivar_getTypeEncoding(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the offset of an instance variable. 返回实例变量的偏移量
 * 
 * @param v The instance variable you want to enquire about. 
 * 
 * @return The offset of \e v.
 * 
 * @note For instance variables of type \c id or other object types, call \c object_getIvar
 *  and \c object_setIvar instead of using this offset to access the instance variable data directly. 对于id类型或其他对象类型的变量,调用object_getIvar和object_setIvar,而不是使用此偏移量直接访问实例变量数据。
 */
OBJC_EXPORT ptrdiff_t
ivar_getOffset(Ivar _Nonnull v) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);


/* Working with Properties */ 操作属性

/** 
 * Returns the name of a property.  返回属性名称
 * 
 * @param property The property you want to inquire about.
 * 
 * @return A C string containing the property's name.
 */
OBJC_EXPORT const char * _Nonnull
property_getName(objc_property_t _Nonnull property) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the attribute string of a property. 返回属性的特性字符串
 * 
 * @param property A property.
 *
 * @return A C string containing the property's attributes.
 * 
 * @note The format of the attribute string is described in Declared Properties in Objective-C Runtime Programming Guide. Objective-C运行时编程指南中的声明属性中描述了属性字符串的格式。
 */
OBJC_EXPORT const char * _Nullable
property_getAttributes(objc_property_t _Nonnull property) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns an array of property attributes for a property.  返回属性的特性数组
 * 
 * @param property The property whose attributes you want copied.
 * @param outCount The number of attributes returned in the array.
 * 
 * @return An array of property attributes; must be free'd() by the caller.  返回一个属性特性数组,必须有调用者释放
 */
OBJC_EXPORT objc_property_attribute_t * _Nullable
property_copyAttributeList(objc_property_t _Nonnull property,
                           unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Returns the value of a property attribute given the attribute name. 返回属性给定特征名称的值
 * 
 * @param property The property whose attribute value you are interested in.
 * @param attributeName C string representing the attribute name.
 *
 * @return The value string of the attribute \e attributeName if it exists in
 *  \e property, \c nil otherwise.  如果存在返回属性特征的值字符串,否则返回nil
 */
OBJC_EXPORT char * _Nullable
property_copyAttributeValue(objc_property_t _Nonnull property,
                            const char * _Nonnull attributeName)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);


/* Working with Protocols */操作协议

/** 
 * Returns a specified protocol. 获取指定协议
 * 
 * @param name The name of a protocol. 协议的名称
 * 
 * @return The protocol named \e name, or \c NULL if no protocol named \e name could be found.  返回对应名称的协议,如果不能找到返回NULL
 * 
 * @note This function acquires the runtime lock. 注意这个函数需要运行时锁
 */
OBJC_EXPORT Protocol * _Nullable
objc_getProtocol(const char * _Nonnull name)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns an array of all the protocols known to the runtime. 返回运行时内已知的所有协议的数组
 * 
 * @param outCount Upon return, contains the number of protocols in the returned array.
 * 
 * @return A C array of all the protocols known to the runtime. The array contains \c *outCount
 *  pointers followed by a \c NULL terminator. You must free the list with \c free().返回运行时已知的所有协议的C数组。 该数组包含* outCount指针,后跟NULL结束符。 您必须免费()列表。
 * 
 * @note This function acquires the runtime lock.  这个函数需要运行时锁
 */
OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable
objc_copyProtocolList(unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a Boolean value that indicates whether one protocol conforms to another protocol. 返回一个布尔值,表示一个协议是否实现了另一个协议
 * 
 * @param proto A protocol.
 * @param other A protocol.
 * 
 * @return \c YES if \e proto conforms to \e other, otherwise \c NO. 如果符合返回YES,否则返回NO
 * 
 * @note One protocol can incorporate other protocols using the same syntax 
 *  that classes use to adopt a protocol:
 *  \code
 *  @protocol ProtocolName < protocol list >
 *  \endcode
 *  All the protocols listed between angle brackets are considered part of the ProtocolName protocol. 一种协议可以使用与类采用协议相同的语法来结合其他协议:@protocol ProtocolName <protocol list>。在尖括号之间列出的所有协议都被认为是ProtocolName协议的一部分。
 */
OBJC_EXPORT BOOL
protocol_conformsToProtocol(Protocol * _Nullable proto,
                            Protocol * _Nullable other)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a Boolean value that indicates whether two protocols are equal. 返回一个布尔值,表示两个协议是否相同
 * 
 * @param proto A protocol.
 * @param other A protocol.
 * 
 * @return \c YES if \e proto is the same as \e other, otherwise \c NO. 如果相同返回YES,否则NO
 */
OBJC_EXPORT BOOL
protocol_isEqual(Protocol * _Nullable proto, Protocol * _Nullable other)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the name of a protocol. 返回协议的名称
 * 
 * @param p A protocol.
 * 
 * @return The name of the protocol \e p as a C string. 返回的名称是一个C字符串
 */
OBJC_EXPORT const char * _Nonnull
protocol_getName(Protocol * _Nonnull proto)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a method description structure for a specified method of a given protocol. 返回给定协议的指定方法的方法描述结构。
 * 
 * @param p A protocol.
 * @param aSel A selector.
 * @param isRequiredMethod A Boolean value that indicates whether aSel is a required method. 判断是不是必须方法
 * @param isInstanceMethod A Boolean value that indicates whether aSel is an instance method. 是不是实例方法
 * 
 * @return An \c objc_method_description structure that describes the method specified by \e aSel,
 *  \e isRequiredMethod, and \e isInstanceMethod for the protocol \e p.
 *  If the protocol does not contain the specified method, returns an \c objc_method_description structure
 *  with the value \c {NULL, \c NULL}. return描述由协议p的aSel,isRequiredMethod和isInstanceMethod指定的方法的objc_method_description结构。 如果协议不包含指定的方法,则返回值为{NULL,NULL}的objc_method_description结构。
 * 
 * @note This function recursively searches any protocols that this protocol conforms to. 此函数递归搜索此协议符合的任何协议。
 */
OBJC_EXPORT struct objc_method_description
protocol_getMethodDescription(Protocol * _Nonnull proto, SEL _Nonnull aSel,
                              BOOL isRequiredMethod, BOOL isInstanceMethod)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns an array of method descriptions of methods meeting a given specification for a given protocol. 返回满足给定协议给定规范的方法的方法描述数组。
 * 
 * @param p A protocol.
 * @param isRequiredMethod A Boolean value that indicates whether returned methods should
 *  be required methods (pass YES to specify required methods).  isRequiredMethod一个布尔值,指示返回的方法是否是必需的方法(通过YES指定所需的方法)。
 * @param isInstanceMethod A Boolean value that indicates whether returned methods should
 *  be instance methods (pass YES to specify instance methods). isInstanceMethod一个布尔值,指示返回的方法是否应该是实例方法(传递YES以指定实例方法)。
 * @param outCount Upon return, contains the number of method description structures in the returned array.
 * 
 * @return A C array of \c objc_method_description structures containing the names and types of \e p's methods 
 *  specified by \e isRequiredMethod and \e isInstanceMethod. The array contains \c *outCount pointers followed
 *  by a \c NULL terminator. You must free the list with \c free().
 *  If the protocol declares no methods that meet the specification, \c NULL is returned and \c *outCount is 0.  返回一个包含由isRequiredMethod和isInstanceMethod指定的p的方法的名称和类型的objc_method_description结构的C数组。 该数组包含* outCount指针,后跟NULL结束符。 您必须免费()列表。 如果协议声明没有符合规范的方法,则返回NULL并且* outCount为0。
 * 
 * @note Methods in other protocols adopted by this protocol are not included. 不包括本协议采用的其他协议中的方法。
 */
OBJC_EXPORT struct objc_method_description * _Nullable
protocol_copyMethodDescriptionList(Protocol * _Nonnull proto,
                                   BOOL isRequiredMethod,
                                   BOOL isInstanceMethod,
                                   unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the specified property of a given protocol. 返回给定协议的指定属性。
 * 
 * @param proto A protocol.
 * @param name The name of a property.
 * @param isRequiredProperty \c YES searches for a required property, \c NO searches for an optional property.
 * @param isInstanceProperty \c YES searches for an instance property, \c NO searches for a class property.
 * 
 * @return The property specified by \e name, \e isRequiredProperty, and \e isInstanceProperty for \e proto,
 *  or \c NULL if none of \e proto's properties meets the specification.
 */
OBJC_EXPORT objc_property_t _Nullable
protocol_getProperty(Protocol * _Nonnull proto,
                     const char * _Nonnull name,
                     BOOL isRequiredProperty, BOOL isInstanceProperty)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns an array of the required instance properties declared by a protocol. 返回由协议声明的必需实现属性的数组。
 * 
 * @note Identical to 
 * \code
 * protocol_copyPropertyList2(proto, outCount, YES, YES);
 * \endcode
 */
OBJC_EXPORT objc_property_t _Nonnull * _Nullable
protocol_copyPropertyList(Protocol * _Nonnull proto,
                          unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns an array of properties declared by a protocol. 返回协议声明的属性构成的数组
 * 
 * @param proto A protocol.
 * @param outCount Upon return, contains the number of elements in the returned array.
 * @param isRequiredProperty \c YES returns required properties, \c NO returns optional properties.
 * @param isInstanceProperty \c YES returns instance properties, \c NO returns class properties.
 * 
 * @return A C array of pointers of type \c objc_property_t describing the properties declared by \e proto.
 *  Any properties declared by other protocols adopted by this protocol are not included. The array contains
 *  \c *outCount pointers followed by a \c NULL terminator. You must free the array with \c free().
 *  If the protocol declares no matching properties, \c NULL is returned and \c *outCount is \c 0.
 */
OBJC_EXPORT objc_property_t _Nonnull * _Nullable
protocol_copyPropertyList2(Protocol * _Nonnull proto,
                           unsigned int * _Nullable outCount,
                           BOOL isRequiredProperty, BOOL isInstanceProperty)
    OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);

/** 
 * Returns an array of the protocols adopted by a protocol.  返回协议采用的协议数组。
 * 
 * @param proto A protocol.
 * @param outCount Upon return, contains the number of elements in the returned array.
 * 
 * @return A C array of protocols adopted by \e proto. The array contains \e *outCount pointers
 *  followed by a \c NULL terminator. You must free the array with \c free().
 *  If the protocol declares no properties, \c NULL is returned and \c *outCount is \c 0. return proto采用的C数组协议。 该数组包含* outCount指针,后跟NULL结束符。 你必须用free()释放数组。 如果协议声明没有属性,则返回NULL,* outCount为0。
 */
OBJC_EXPORT Protocol * __unsafe_unretained _Nonnull * _Nullable
protocol_copyProtocolList(Protocol * _Nonnull proto,
                          unsigned int * _Nullable outCount)
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Creates a new protocol instance that cannot be used until registered with
 * \c objc_registerProtocol() 创建一个新的协议实例,在使用objc_registerProtocol()注册之前不能使用它
 * 
 * @param name The name of the protocol to create.
 *
 * @return The Protocol instance on success, \c nil if a protocol
 *  with the same name already exists. 
 * @note There is no dispose method for this. 
 */
OBJC_EXPORT Protocol * _Nullable
objc_allocateProtocol(const char * _Nonnull name) 
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Registers a newly constructed protocol with the runtime. The protocol
 * will be ready for use and is immutable after this. 用运行时注册一个新构建的协议。 该协议将准备好使用,并在此之后不可变。
 * 
 * @param proto The protocol you want to register.
 */
OBJC_EXPORT void
objc_registerProtocol(Protocol * _Nonnull proto) 
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Adds a method to a protocol. The protocol must be under construction. 向协议添加一个方法。 该协议必须在建设中。
 * 
 * @param proto The protocol to add a method to.
 * @param name The name of the method to add.
 * @param types A C string that represents the method signature.
 * @param isRequiredMethod YES if the method is not an optional method.
 * @param isInstanceMethod YES if the method is an instance method. 
 */
OBJC_EXPORT void
protocol_addMethodDescription(Protocol * _Nonnull proto, SEL _Nonnull name,
                              const char * _Nullable types,
                              BOOL isRequiredMethod, BOOL isInstanceMethod) 
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Adds an incorporated protocol to another protocol. The protocol being
 * added to must still be under construction, while the additional protocol
 * must be already constructed. 将合并的协议添加到另一个协议。 被添加到的协议必须仍在建设中,而附加协议必须已经构建。
 * 
 * @param proto The protocol you want to add to, it must be under construction.
 * @param addition The protocol you want to incorporate into \e proto, it must be registered.
 */
OBJC_EXPORT void
protocol_addProtocol(Protocol * _Nonnull proto, Protocol * _Nonnull addition) 
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Adds a property to a protocol. The protocol must be under construction.  将一个属性添加到协议。 该协议必须在建设中。
 * 
 * @param proto The protocol to add a property to.
 * @param name The name of the property.
 * @param attributes An array of property attributes.
 * @param attributeCount The number of attributes in \e attributes.
 * @param isRequiredProperty YES if the property (accessor methods) is not optional. 
 * @param isInstanceProperty YES if the property (accessor methods) are instance methods. 
 *  This is the only case allowed fo a property, as a result, setting this to NO will 
 *  not add the property to the protocol at all. 
 */
OBJC_EXPORT void
protocol_addProperty(Protocol * _Nonnull proto, const char * _Nonnull name,
                     const objc_property_attribute_t * _Nullable attributes,
                     unsigned int attributeCount,
                     BOOL isRequiredProperty, BOOL isInstanceProperty)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);


/* Working with Libraries */ 操作库

/** 
 * Returns the names of all the loaded Objective-C frameworks and dynamic
 * libraries. 返回所有加载的Objective-C frameworks和静态库
 * 
 * @param outCount The number of names returned.
 * 
 * @return An array of C strings of names. Must be free()'d by caller. 返回一个C字符串的名称构成的数组,调用者必须释放
 */
OBJC_EXPORT const char * _Nonnull * _Nonnull
objc_copyImageNames(unsigned int * _Nullable outCount) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the dynamic library name a class originated from. 返回一个类源自的动态库名称。
 * 
 * @param cls The class you are inquiring about.
 * 
 * @return The name of the library containing this class.
 */
OBJC_EXPORT const char * _Nullable
class_getImageName(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns the names of all the classes within a library. 返回在一个库内的所有的类名称
 * 
 * @param image The library or framework you are inquiring about. 
 * @param outCount The number of class names returned.
 * 
 * @return An array of C strings representing the class names. c字符串数组
 */
OBJC_EXPORT const char * _Nonnull * _Nullable
objc_copyClassNamesForImage(const char * _Nonnull image,
                            unsigned int * _Nullable outCount) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);


/* Working with Selectors */ 操作选择器

/** 
 * Returns the name of the method specified by a given selector. 返回指定选择器的方法的名称
 * 
 * @param sel A pointer of type \c SEL. Pass the selector whose name you wish to determine.   SEL类型的指针。 通过您希望确定其名称的选择器。
 *  
 * @return A C string indicating the name of the selector.
 */
OBJC_EXPORT const char * _Nonnull
sel_getName(SEL _Nonnull sel)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);


/** 
 * Registers a method with the Objective-C runtime system, maps the method 
 * name to a selector, and returns the selector value. 使用Objective-C运行时系统注册一个方法,将方法名映射到选择器并返回选择器值。
 * 
 * @param str A pointer to a C string. Pass the name of the method you wish to register.
 * 
 * @return A pointer of type SEL specifying the selector for the named method.
 * 
 * @note You must register a method name with the Objective-C runtime system to obtain the
 *  method’s selector before you can add the method to a class definition. If the method name
 *  has already been registered, this function simply returns the selector.
 */
OBJC_EXPORT SEL _Nonnull
sel_registerName(const char * _Nonnull str)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

/** 
 * Returns a Boolean value that indicates whether two selectors are equal. 返回布尔值 表示两个选择器是否相等
 * 
 * @param lhs The selector to compare with rhs.
 * @param rhs The selector to compare with lhs.
 * 
 * @return \c YES if \e lhs and \e rhs are equal, otherwise \c NO.
 * 
 * @note sel_isEqual is equivalent to ==.
 */
OBJC_EXPORT BOOL
sel_isEqual(SEL _Nonnull lhs, SEL _Nonnull rhs) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);


/* Objective-C Language Features */ Objective-C语言特性

/** 
 * This function is inserted by the compiler when a mutation
 * is detected during a foreach iteration. It gets called 
 * when a mutation occurs, and the enumerationMutationHandler
 * is enacted if it is set up. A fatal error occurs if a handler is not set up.       当在foreach迭代过程中检测到突变时,编译器插入此函数。 它在变异发生时被调用,并且如果设置了enumerationMutationHandler,则会执行。 如果未设置处理程序,则会发生致命错误。
 *
 * @param obj The object being mutated. 发生变化的对象
 * 
 */
OBJC_EXPORT void
objc_enumerationMutation(id _Nonnull obj) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Sets the current mutation handler.  设置当前编译回调
 * 
 * @param handler Function pointer to the new mutation handler.
 */
OBJC_EXPORT void
objc_setEnumerationMutationHandler(void (*_Nullable handler)(id _Nonnull )) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Set the function to be called by objc_msgForward. 设置由objc_msgForward调用的函数。
 * 
 * @param fwd Function to be jumped to by objc_msgForward.
 * @param fwd_stret Function to be jumped to by objc_msgForward_stret.
 * 
 * @see message.h::_objc_msgForward
 */
OBJC_EXPORT void
objc_setForwardHandler(void * _Nonnull fwd, void * _Nonnull fwd_stret) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

/** 
 * Creates a pointer to a function that will call the block
 * when the method is called. 创建一个指向调用该方法时将调用该块的函数的指针。
 * 
 * @param block The block that implements this method. Its signature should
 *  be: method_return_type ^(id self, method_args...). 
 *  The selector is not available as a parameter to this block.
 *  The block is copied with \c Block_copy().  实现此方法的块。 它的签名应该是:method_return_type ^(id self,method_args ...)。 该选择器不可用作该块的参数。该块用\ c Block_copy()复制。
 * 
 * @return The IMP that calls this block. Must be disposed of with
 *  \c imp_removeBlock.
 */
OBJC_EXPORT IMP _Nonnull
imp_implementationWithBlock(id _Nonnull block)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Return the block associated with an IMP that was created using
 * \c imp_implementationWithBlock. 返回与使用imp_implementationWithBlock创建的IMP关联的块。
 * 
 * @param anImp The IMP that calls this block.参数 animp 调用这个块的IMP
 * 
 * @return The block called by \e anImp.
 */
OBJC_EXPORT id _Nullable
imp_getBlock(IMP _Nonnull anImp)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * Disassociates a block from an IMP that was created using
 * \c imp_implementationWithBlock and releases the copy of the 
 * block that was created.从使用imp_implementationWithBlock创建的IMP中分离出一个块,并释放创建的块的副本。
 *  
 * @param anImp An IMP that was created using \c imp_implementationWithBlock.
 * 
 * @return YES if the block was released successfully, NO otherwise. 
 *  (For example, the block might not have been used to create an IMP previously).
 */
OBJC_EXPORT BOOL
imp_removeBlock(IMP _Nonnull anImp)
    OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0);

/** 
 * This loads the object referenced by a weak pointer and returns it, after
 * retaining and autoreleasing the object to ensure that it stays alive
 * long enough for the caller to use it. This function would be used
 * anywhere a __weak variable is used in an expression.    这会加载由弱指针引用的对象,并在保留并自动释放对象之后返回它,以确保它保持足够长的时间以供调用方使用。 这个函数可以在表达式中使用__weak变量的地方使用。
 * 
 * @param location The weak pointer address
 * 
 * @return The object pointed to by \e location, or \c nil if \e *location is \c nil.
 */
OBJC_EXPORT id _Nullable
objc_loadWeak(id _Nullable * _Nonnull location)
    OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);

/** 
 * This function stores a new value into a __weak variable. It would
 * be used anywhere a __weak variable is the target of an assignment. 该函数将一个新值存储到__weak变量中。 它可以在任何地方使用__weak变量作为赋值的目标。
 * 
 * @param location The address of the weak pointer itself
 * @param obj The new object this weak ptr should now point to
 * 
 * @return The value stored into \e location, i.e. \e obj
 */
OBJC_EXPORT id _Nullable
objc_storeWeak(id _Nullable * _Nonnull location, id _Nullable obj) 
    OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);


/* Associative References */ 关联参考

/**
 * Policies related to associative references.
 * These are options to objc_setAssociatedObject() 与关联参考相关的策略。 这些是objc_setAssociatedObject()的选项
 */
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};

/** 
 * Sets an associated value for a given object using a given key and association policy. 使用给定的键和关联策略设置给定对象的关联值。
 * 
 * @param object The source object for the association.
 * @param key The key for the association.
 * @param value The value to associate with the key key for object. Pass nil to clear an existing association.
 * @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
 * 
 * @see objc_setAssociatedObject
 * @see objc_removeAssociatedObjects
 */
OBJC_EXPORT void
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
                         id _Nullable value, objc_AssociationPolicy policy)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);

/** 
 * Returns the value associated with a given object for a given key.只用给定的键和对象返回关联值
 * 
 * @param object The source object for the association.
 * @param key The key for the association.
 * 
 * @return The value associated with the key \e key for \e object.
 * 
 * @see objc_setAssociatedObject
 */
OBJC_EXPORT id _Nullable
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);

/** 
 * Removes all associations for a given object. 移除给定对象上的所有关联
 * 
 * @param object An object that maintains associated objects. 
 * 
 * @note The main purpose of this function is to make it easy to return an object 
 *  to a "pristine state”. You should not use this function for general removal of
 *  associations from objects, since it also removes associations that other clients
 *  may have added to the object. Typically you should use \c objc_setAssociatedObject 
 *  with a nil value to clear an association.   注意此函数的主要目的是使对象返回到“原始状态”变得容易。不应该使用此函数来从对象中删除关联,因为它还会删除其他客户端可能添加到 通常你应该使用objc_setAssociatedObject和一个零值来清除关联。
 * 
 * @see objc_setAssociatedObject
 * @see objc_getAssociatedObject
 */
OBJC_EXPORT void
objc_removeAssociatedObjects(id _Nonnull object)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);


#define _C_ID       '@'
#define _C_CLASS    '#'
#define _C_SEL      ':'
#define _C_CHR      'c'
#define _C_UCHR     'C'
#define _C_SHT      's'
#define _C_USHT     'S'
#define _C_INT      'i'
#define _C_UINT     'I'
#define _C_LNG      'l'
#define _C_ULNG     'L'
#define _C_LNG_LNG  'q'
#define _C_ULNG_LNG 'Q'
#define _C_FLT      'f'
#define _C_DBL      'd'
#define _C_BFLD     'b'
#define _C_BOOL     'B'
#define _C_VOID     'v'
#define _C_UNDEF    '?'
#define _C_PTR      '^'
#define _C_CHARPTR  '*'
#define _C_ATOM     '%'
#define _C_ARY_B    '['
#define _C_ARY_E    ']'
#define _C_UNION_B  '('
#define _C_UNION_E  ')'
#define _C_STRUCT_B '{'
#define _C_STRUCT_E '}'
#define _C_VECTOR   '!'
#define _C_CONST    'r'


/* Obsolete types */

#if !__OBJC2__

#define CLS_GETINFO(cls,infomask)        ((cls)->info & (infomask))
#define CLS_SETINFO(cls,infomask)        ((cls)->info |= (infomask))

// class is not a metaclass
#define CLS_CLASS               0x1
// class is a metaclass
#define CLS_META                0x2
// class's +initialize method has completed
#define CLS_INITIALIZED         0x4
// class is posing
#define CLS_POSING              0x8
// unused
#define CLS_MAPPED              0x10
// class and subclasses need cache flush during image loading
#define CLS_FLUSH_CACHE         0x20
// method cache should grow when full
#define CLS_GROW_CACHE          0x40
// unused
#define CLS_NEED_BIND           0x80
// methodLists is array of method lists
#define CLS_METHOD_ARRAY        0x100
// the JavaBridge constructs classes with these markers
#define CLS_JAVA_HYBRID         0x200
#define CLS_JAVA_CLASS          0x400
// thread-safe +initialize
#define CLS_INITIALIZING        0x800
// bundle unloading
#define CLS_FROM_BUNDLE         0x1000
// C++ ivar support
#define CLS_HAS_CXX_STRUCTORS   0x2000
// Lazy method list arrays
#define CLS_NO_METHOD_ARRAY     0x4000
// +load implementation
#define CLS_HAS_LOAD_METHOD     0x8000
// objc_allocateClassPair API
#define CLS_CONSTRUCTING        0x10000
// class compiled with bigger class structure
#define CLS_EXT                 0x20000


struct objc_method_description_list {
    int count;
    struct objc_method_description list[1];
};


struct objc_protocol_list {
    struct objc_protocol_list * _Nullable next;
    long count;
    __unsafe_unretained Protocol * _Nullable list[1];
};


struct objc_category {
    char * _Nonnull category_name                            OBJC2_UNAVAILABLE;
    char * _Nonnull class_name                               OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable instance_methods     OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable class_methods        OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;


struct objc_ivar {
    char * _Nullable ivar_name                               OBJC2_UNAVAILABLE;
    char * _Nullable ivar_type                               OBJC2_UNAVAILABLE;
    int ivar_offset                                          OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
}                                                            OBJC2_UNAVAILABLE;

struct objc_ivar_list {
    int ivar_count                                           OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
    /* variable length structure */
    struct objc_ivar ivar_list[1]                            OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;


struct objc_method {
    SEL _Nonnull method_name                                 OBJC2_UNAVAILABLE;
    char * _Nullable method_types                            OBJC2_UNAVAILABLE;
    IMP _Nonnull method_imp                                  OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;

struct objc_method_list {
    struct objc_method_list * _Nullable obsolete             OBJC2_UNAVAILABLE;

    int method_count                                         OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
    /* variable length structure */
    struct objc_method method_list[1]                        OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;


typedef struct objc_symtab *Symtab                           OBJC2_UNAVAILABLE;

struct objc_symtab {
    unsigned long sel_ref_cnt                                OBJC2_UNAVAILABLE;
    SEL _Nonnull * _Nullable refs                            OBJC2_UNAVAILABLE;
    unsigned short cls_def_cnt                               OBJC2_UNAVAILABLE;
    unsigned short cat_def_cnt                               OBJC2_UNAVAILABLE;
    void * _Nullable defs[1] /* variable size */             OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;


typedef struct objc_cache *Cache                             OBJC2_UNAVAILABLE;

#define CACHE_BUCKET_NAME(B)  ((B)->method_name)
#define CACHE_BUCKET_IMP(B)   ((B)->method_imp)
#define CACHE_BUCKET_VALID(B) (B)
#ifndef __LP64__
#define CACHE_HASH(sel, mask) (((uintptr_t)(sel)>>2) & (mask))
#else
#define CACHE_HASH(sel, mask) (((unsigned int)((uintptr_t)(sel)>>3)) & (mask))
#endif
struct objc_cache {
    unsigned int mask /* total = mask + 1 */                 OBJC2_UNAVAILABLE;
    unsigned int occupied                                    OBJC2_UNAVAILABLE;
    Method _Nullable buckets[1]                              OBJC2_UNAVAILABLE;
};


typedef struct objc_module *Module                           OBJC2_UNAVAILABLE;

struct objc_module {
    unsigned long version                                    OBJC2_UNAVAILABLE;
    unsigned long size                                       OBJC2_UNAVAILABLE;
    const char * _Nullable name                              OBJC2_UNAVAILABLE;
    Symtab _Nullable symtab                                  OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;

#else

struct objc_method_list;

#endif


/* Obsolete functions */

OBJC_EXPORT IMP _Nullable
class_lookupMethod(Class _Nullable cls, SEL _Nonnull sel) 
    __OSX_DEPRECATED(10.0, 10.5, "use class_getMethodImplementation instead") 
    __IOS_DEPRECATED(2.0, 2.0, "use class_getMethodImplementation instead") 
    __TVOS_DEPRECATED(9.0, 9.0, "use class_getMethodImplementation instead") 
    __WATCHOS_DEPRECATED(1.0, 1.0, "use class_getMethodImplementation instead")
    __BRIDGEOS_DEPRECATED(2.0, 2.0, "use class_getMethodImplementation instead");
OBJC_EXPORT BOOL
class_respondsToMethod(Class _Nullable cls, SEL _Nonnull sel)
    __OSX_DEPRECATED(10.0, 10.5, "use class_respondsToSelector instead") 
    __IOS_DEPRECATED(2.0, 2.0, "use class_respondsToSelector instead") 
    __TVOS_DEPRECATED(9.0, 9.0, "use class_respondsToSelector instead") 
    __WATCHOS_DEPRECATED(1.0, 1.0, "use class_respondsToSelector instead")
    __BRIDGEOS_DEPRECATED(2.0, 2.0, "use class_respondsToSelector instead");

OBJC_EXPORT void
_objc_flush_caches(Class _Nullable cls) 
    __OSX_DEPRECATED(10.0, 10.5, "not recommended") 
    __IOS_DEPRECATED(2.0, 2.0, "not recommended") 
    __TVOS_DEPRECATED(9.0, 9.0, "not recommended") 
    __WATCHOS_DEPRECATED(1.0, 1.0, "not recommended")
    __BRIDGEOS_DEPRECATED(2.0, 2.0, "not recommended");

OBJC_EXPORT id _Nullable
object_copyFromZone(id _Nullable anObject, size_t nBytes, void * _Nullable z) 
    __OSX_DEPRECATED(10.0, 10.5, "use object_copy instead") 
    __IOS_UNAVAILABLE __TVOS_UNAVAILABLE
    __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE
    OBJC_ARC_UNAVAILABLE;

OBJC_EXPORT id _Nullable
object_realloc(id _Nullable anObject, size_t nBytes)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT id _Nullable
object_reallocFromZone(id _Nullable anObject, size_t nBytes, void * _Nullable z)
    OBJC2_UNAVAILABLE;

#define OBSOLETE_OBJC_GETCLASSES 1
OBJC_EXPORT void * _Nonnull
objc_getClasses(void)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT void
objc_addClass(Class _Nonnull myClass)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT void
objc_setClassHandler(int (* _Nullable )(const char * _Nonnull))
    OBJC2_UNAVAILABLE;

OBJC_EXPORT void
objc_setMultithreaded(BOOL flag)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT id _Nullable
class_createInstanceFromZone(Class _Nullable, size_t idxIvars,
                             void * _Nullable z)
    __OSX_DEPRECATED(10.0, 10.5, "use class_createInstance instead") 
    __IOS_UNAVAILABLE __TVOS_UNAVAILABLE
    __WATCHOS_UNAVAILABLE __BRIDGEOS_UNAVAILABLE
    OBJC_ARC_UNAVAILABLE;

OBJC_EXPORT void
class_addMethods(Class _Nullable, struct objc_method_list * _Nonnull)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT void
class_removeMethods(Class _Nullable, struct objc_method_list * _Nonnull)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT void
_objc_resolve_categories_for_class(Class _Nonnull cls)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT Class _Nonnull
class_poseAs(Class _Nonnull imposter, Class _Nonnull original)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT unsigned int
method_getSizeOfArguments(Method _Nonnull m)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT unsigned
method_getArgumentInfo(struct objc_method * _Nonnull m, int arg,
                       const char * _Nullable * _Nonnull type,
                       int * _Nonnull offset)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT Class _Nullable
objc_getOrigClass(const char * _Nonnull name)
    OBJC2_UNAVAILABLE;

#define OBJC_NEXT_METHOD_LIST 1
OBJC_EXPORT struct objc_method_list * _Nullable
class_nextMethodList(Class _Nullable, void * _Nullable * _Nullable)
    OBJC2_UNAVAILABLE;
// usage for nextMethodList
//
// void *iterator = 0;
// struct objc_method_list *mlist;
// while ( mlist = class_nextMethodList( cls, &iterator ) )
//    ;
 
OBJC_EXPORT id _Nullable
(* _Nonnull _alloc)(Class _Nullable, size_t)
    OBJC2_UNAVAILABLE;

OBJC_EXPORT id _Nullable
(* _Nonnull _copy)(id _Nullable, size_t)
     OBJC2_UNAVAILABLE;
     
OBJC_EXPORT id _Nullable
(* _Nonnull _realloc)(id _Nullable, size_t)
     OBJC2_UNAVAILABLE;

OBJC_EXPORT id _Nullable
(* _Nonnull _dealloc)(id _Nullable)
     OBJC2_UNAVAILABLE;
     
OBJC_EXPORT id _Nullable
(* _Nonnull _zoneAlloc)(Class _Nullable, size_t, void * _Nullable)
     OBJC2_UNAVAILABLE;
     
OBJC_EXPORT id _Nullable
(* _Nonnull _zoneRealloc)(id _Nullable, size_t, void * _Nullable)
     OBJC2_UNAVAILABLE;
     
OBJC_EXPORT id _Nullable
(* _Nonnull _zoneCopy)(id _Nullable, size_t, void * _Nullable)
     OBJC2_UNAVAILABLE;
     
OBJC_EXPORT void
(* _Nonnull _error)(id _Nullable, const char * _Nonnull, va_list)
     OBJC2_UNAVAILABLE;

#endif
  1. 使用例子
    2.1 获取当前项目所有类的名称

     + (NSArray<NSString *>*)appClasses{
         NSArray * result = nil;
         NSString * executablePath = [[NSBundle mainBundle] executablePath];
         unsigned int classNamesCount = 0;
         const char **classNames = objc_copyClassNamesForImage([executablePath UTF8String], &classNamesCount);
         if (classNames) {
             NSMutableArray *classNameStrings = [NSMutableArray array];
             for (unsigned int i = 0; i < classNamesCount; i++) {
                 const char *className = classNames[i];
                 NSString *classNameString = [NSString stringWithUTF8String:className];
                 [classNameStrings addObject:classNameString];
             }
             result = [classNameStrings sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
             free(classNames);
         }
         return result;
     }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容