Runtime官方文档学习--和Runtime交互
Objective-C programs interact with the runtime system at three distinct levels: through Objective-C source code; through methods defined in the
NSObject
class of the Foundation framework; and through direct calls to runtime functions.
Objective-C程序在三个不同的级别和运行时系统进行交互:1.通过Objective-C源代码;2.通过Foundation框架中NSObject类定义的方法;3.通过直接调用运行时函数。
1.通过Objective-C源代码
For the most part, the runtime system works automatically and behind the scenes. You use it just by writing and compiling Objective-C source code.
在大多数情况下,运行时系统会在后台自动运行。你只需要通过编写和编译Objective-C源代码来使用它。
When you compile code containing Objective-C classes and methods, the compiler creates the data structures and function calls that implement the dynamic characteristics of the language. The data structures capture information found in class and category definitions and in protocol declarations; they include the class and protocol objects discussed in Defining a Class and Protocols in The Objective-C Programming Language, as well as method selectors, instance variable templates, and other information distilled from source code. The principal runtime function is the one that sends messages, as described in Messaging. It’s invoked by source-code message expressions.
当你编译包含Objective-C类和方法的代码时,编译器会创建实现语言动态特性的数据结构和函数调用。数据结构会捕获在类和类别定义以及协议声明中找到的信息;其中包括在Objective-C编程语言中的定义类和协议中讨论过的类和协议对象,以及方法选择器,实例变量模板和其他从源代码中提取的信息。主要的运行时函数是发送消息,正如消息所述。它由源代码消息表达式所调用。
我们所编写的Objective-C代码,会被编译器转化为运行时代码,在运行时确定数据结构和函数调用,所以我们平时编写OC代码就是在同运行时系统进行交互。
2.NSObject方法
Most objects in Cocoa are subclasses of the
NSObject
class, so most objects inherit the methods it defines. (The notable exception is theNSProxy
class; see Message Forwarding for more information.) Its methods therefore establish behaviors that are inherent to every instance and every class object. However, in a few cases, theNSObject
class merely defines a template for how something should be done; it doesn’t provide all the necessary code itself.
Cocoa中大多数类都是NSObject类的子类,因此大部分类都继承了它定义的方法。(例外是NSProxy
类;查看消息转发获取更多信息。)因此它的方法建立了每个实例和类对象固有的行为。然而,在少数情况下,NSObject类之定义了如何完成一件事情的模板,它自己并不会提供所有必要的代码。
项目开发中经常采用这种方式进行框架的搭建,比如,通常会自己创建一个UIViewController的子类BaseViewController来作为所有Controller的基类,把通用的属性和方法定义在基类中,这样所有的子类都可以调用和自定义实现。
For example, the
NSObject
class defines adescription
instance method that returns a string describing the contents of the class. This is primarily used for debugging—the GDBprint-object
command prints the string returned from this method.NSObject
’s implementation of this method doesn’t know what the class contains, so it returns a string with the name and address of the object. Subclasses ofNSObject
can implement this method to return more details. For example, the Foundation classNSArray
returns a list of descriptions of the objects it contains.
例如,NSObject类定义了一个实例方法description
,该方法返回一个描述类内容的字符串。这个主要用于调试---GDB 的print-object
命令打印这个方法返回的字符串。NSObject中这个方法的实现不知道这个类包含什么,因此它返回一个包含当前对象名称和地址的字符串。NSObject的子类可以实现这个方法来返回更多详细内容。例如,Foundation中的NSarray
类返回了一个它包含的所有对象描述的列表。
NSObject类中描述对象的方法还有dubugDescription
,当直接用NSLog打印对象时调用的是description,在控制台中用命令打印对象时调用的是dubugDescription,而debugDescrption默认实现和description一样,也是打印类名和地址。这两个方法分别有类方法和实例方法,打印对象时调用实例方法,打印类时调用类方法。
- (NSString *)description {
return @"instance description";
}
+ (NSString *)description {
return @"class description";
}
- (NSString *)debugDescription {
return @"instance debugDescription";
}
+ (NSString *)debugDescription {
return @"class debugDescription";
}
Person *p = [Person new];
NSLog(@"%@", p); // instance description
NSLog(@"%@", [Person description]); // class description
(lldb) po p
instance debugDescription
(lldb) po [Person class]
class debugDescription
Some of the
NSObject
methods simply query the runtime system for information. These methods allow objects to perform introspection. Examples of such methods are theclass
method, which asks an object to identify its class;isKindOfClass:
andisMemberOfClass:
, which test an object’s position in the inheritance hierarchy;respondsToSelector:
, which indicates whether an object can accept a particular message;conformsToProtocol:
, which indicates whether an object claims to implement the methods defined in a specific protocol; andmethodForSelector:
, which provides the address of a method’s implementation. Methods like these give an object the ability to introspect about itself.
一些NSObject方法只是简单地查询运行时系统的信息。这些方法允许对象进行自我检查。这些方法的例子是类方法,它要求对象识别自身的类。isKindOfClass:
和isMemberOfClass:
测试一个对象在集成层次中的位置;respondsToSelector:
表示一个对象是否能接收一个特定的消息;conformsToProtocol:
表示一个对象是否声明要实现在指定的协议中定义的方法;methodForSelector:
提供了一个方法实现的地址。像以上这些方法让一个对象能够自我检查。
// 某个类(对象)是否是某个类(的实例)或其子类(的实例)
- (BOOL)isKindOfClass:(Class)aClass;
// 某个类(对象)是否属于某个类(的实例)
- (BOOL)isMemberOfClass:(Class)aClass;
// 一个对象是否实现了指定协议的方法
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
// 一个对象是否能响应指定方法
- (BOOL)respondsToSelector:(SEL)aSelector;
// 返回指定方法的实现
- (IMP)methodForSelector:(SEL)aSelector;
3.运行时函数
The runtime system is a dynamic shared library with a public interface consisting of a set of functions and data structures in the header files located within the directory
/usr/include/objc
. Many of these functions allow you to use plain C to replicate what the compiler does when you write Objective-C code. Others form the basis for functionality exported through the methods of theNSObject
class. These functions make it possible to develop other interfaces to the runtime system and produce tools that augment the development environment; they’re not needed when programming in Objective-C. However, a few of the runtime functions might on occasion be useful when writing an Objective-C program. All of these functions are documented in Objective-C Runtime Reference.
运行时系统是一个动态共享库,其公共接口由位于/usr/include/objc
目录的头文件中的一些列函数和数据结构组成。其中许多函数允许你使用plain C来复制当你编写Objective-C代码时编译器所执行的操作。其他构成了通过NSObject类的方法导出的功能的基础。这些函数可以开发运行时系统的其他接口,生成增强开发环境的工具;这些函数在Objective-C编程时是不需要的。然而,在编写Objective-C程序时,一些运行时函数可能会有用。所有这些函数都记录在Objective-C Runtime Reference中。