runtime文档学习笔记

第一次学习:

文档地址:

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008048-CH1-SW1

1、The Objective-C language defers as many as decisions as it can from compile time and link time to runtime。

oc语言推迟了从编译时间和连接时间到运行时间的很多决策。

2、Whenever possible, it does things dynamically.

不论什么时候,它做这些事是动态的。

3、The means that language requires not just a compile ,but also a runtime system to execute the complied code.The runtime system acts as a kind of operating system for the Objective-C language; it’s what makes the language work.

这意味着这语言不仅需要一个编译器,也需要一个运行系统来执行编译的代码。运行时系统充当C语言的一类操作系统,它是驱动语言工作的东西。

4、it (document)examines the paradigms for dynamically loading new classed at runtime, and forwarding messages to other objects.it also provides information about how you can find information about objects while your program is running.

文件在运行时中探讨了动态加载新类的范例,并动态的将消息发给其他对象。当你的项目正在运行的时候,文件也提供了怎么找到关于对象的信息。

5、There are different versions of the Objective-C runtime on different platforms.The modern version was introduced with Objective-C 2.0 and includes a number of new features. The programming interface for the legacy version of the runtime is described in Objective-C 1 Runtime Reference

在不同的平台又不同的版本,最近的版本在oc2.0有介绍,包含很多新特征,对于遗留版本的程序接口在oc1 运行时索引有描述。

6、The most notable new feature is that instance variables in the modern runtime are “non-fragile”:

最显著的新特征是在现在版本的运行时实例变量不易碎.

 

  • 7、In the legacy runtime, if you change the layout of instance variables in a class, you must recompile classes that inherit from it.
  • 在以前的runtime,如果你改变了一个类的实例变量的布局,那你必须重新编译继承于有改变的那个类的类。(父类动了,要重新编译)
  • 8、In the modern runtime, if you change the layout of instance variables in a class, you do not have to recompile classes that inherit from it.
  • 现在版运行时,如果你改变一个类中的实例变量的布局,你不需要重新编译继承于它的类。
  • 9、In addition, the modern runtime supports instance variable synthesis for declared properties (see Declared Properties in The Objective-C Programming Language).

除此之外,现在版运行时通过声明属性支持实例变量的合并。

10、iPhone applications and 64-bit programs on OS X v10.5 and later use the modern version of the runtime.

iPhone 应用程序和对OSX 10.5的64字节的项目以及以后采用modeL版本

Other programs (32-bit programs on OSX desktop) use the legacy version of the runtime 

在OSX上线32字节的程序应用legacy 版本

11、Objective-C programs interact with the runtime system at three distinct levels: through Objective-C source code; through methods defined in theNSObject class of the Foundation framework; and through direct calls to runtime functions.

oc项目在三个不同的层次交互运行时系统:通过oc源码,通过定义在NSObject里面的方法,通过直接对运行时函数的调用。

12、Objective-C Source Code oc源码

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.

对于大多数部分,运行时是自动在幕后工作,你能通过写和编译源码来使用它。(也就是正常的的oc代码就会直接走运行时系统)。

13、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

当你编译包含oc类和方法的代码时,编译器创建数据结构和函数功能,用以实现这门语言的动态特征。

14、

The data structures capture information found in class and category definitions and in protocol declarations

数据结构在类、类目定义以及协议声明中抓信息

15、 they (指14条里面的信息)include the class and protocol objects discussed in Defining a Class and Protocols , as well as method selectors, instance variable templates, and other information distilled from source code.

他们包含类和协议以及方法选择器,实例变量模板以及从源码中分析(原意是蒸馏)出的信息。

16、 The principal runtime function is the one that sends messages, as described inMessaging. It’s invoked by source-code message expressions.

最重要的运行时功能是发信息的,它被源码信息表述唤醒.

17、NSObject Methods

However, in a few cases, the NSObject class merely defines a template for how something should be done; it doesn’t provide all the necessary code itself

然而,在一些例子,NSObject 类仅仅定义了一个怎么做的模板,它并没有提供足够的码。

18、NSObject’s implementation of this method(discription) doesn’t know what the class contains, so it returns a string with the name and address of the object.

这个方法的实现不知道这个类包含什么,所有它返回一个那个对象的名字和地址的字符串(@“<Person: 0x600000220880>”)

19、Subclasses ofNSObject can implement this method(discription) to return more details. For example, the Foundation classNSArray returns a list of descriptions of the objects it contains.

NSObject能返回更多细节。例如,数组就会返回它包含的对象。

20、The notable exception is theNSProxy class; 这个类不继承于NSObject

21、Some of the NSObject methods simply query the runtime system for information. These methods allow objects to perform introspection. Examples of such methods are the class method

NSObject方法里面的一些简单的问询运行时信息,这些方法允许对象自省,这样的例子是类方法。

22、isKindOfClass

which asks an object to identify its class

请求对象鉴别它的类。

23、isMemberOfClass:, which test an object’s position in the inheritance hierarchy;

这个类测试层级结构的位置。是不是子类。

24、respondsToSelector:, which indicates whether an object can accept a particular message

显示一个对象能否接受一个特殊的消息

25、conformsToProtocol:, which indicates whether an object claims to implement the methods defined in a specific protocol;

显示一个对象是否声明实现了在一个协议里面的方法

26、andmethodForSelector:, which provides the address of a method’s implementation. 

这个方法提供了一个方法实现的地址.

- (IMP)methodForSelector:(SEL)aSelector;

+ (IMP)instanceMethodForSelector:(SEL)aSelector;

IMP是implementation的缩写,它oc方法实现代码块的地址,可像C函数一样调用

27、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.

运行时系统是一个动态的分享库,它有一些公共的接口,这些接口包含一系列的函数和数据结构在一个头文件中,这个头文件在目录/usr/include/objc下。

28、 Many of these functions allow you to use plain C to replicate what the compiler does when you write Objective-C code

这些函数的许多允许你运用清晰的c语言来复制展示,当你写oc代码的时候,你的编译器做了什么。

29、Others form the basis for functionality exported through the methods of theNSObject class

其他的形成了函数的基础,这些函数是通过NSObject类的方法导出的。

30、 These functions make it possible to develop other interfaces to the runtime system and produce tools that augment the development environment;

这些函数让开发其他对运行时系统的接口成为可能,和生产增加开发环境的工具

31、 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

在用oc写项目时,他们不是一定需要的,但是,少数运行时函数当写一个oc项目时,也是有用的。

32、messaging

In Objective -C,messages are’t bound to method implementations until runtime

消息直到了运行时才会方法实现。

33、[receiver message]

——>>objc_msgSend(receiver, selector)

34、Any arguments passed in the message are also handed to objc_msgSend:

消息中的任何参数也会包含在这个方法里

objc_msgSend(receiver, selector, arg1, arg2, ….)

arg1和arg2是message的参数

35、动态绑定做的事

It first finds the procedure (method implementation) that the selector refers to. Since the same method can be implemented differently by separate classes, the precise procedure that it finds depends on the class of the receiver.

它首先找到选择器指向的程序,因为相同的方法能在不同的类里实现,它找到精确地程是依赖接收者的类名。

36、It(objc_msgSend) then calls the procedure, passing it the receiving object (a pointer to its data), along with any arguments that were specified for the method.

它然后调用这个程序,将它传给这个接收的对象以及任何参数,这些参数是指定给这个方法的

37、Finally, it passes on the return value of the procedure as its own return value.

最后,她传递这个程序的返回值作为它自己的返回值。

38、The compiler generates calls to the messaging function. You should never call it directly in the code you write.

这个编译器能产生调用那个msg函数,你从来不需要直接调用它。

39、The key to messaging lies in the structures that the compiler builds for each class and object. Every class structure includes these two essential elements

消息传递的关键编译器为每个类和对象建立的结构体中,每个类的结构体包含两个必要的元素。

(1)A pointer to the superclass.

指向超类的指针

(2)A class dispatch table. This table has entries that associate method selectors with the class-specific addresses of the methods they identify. The selector for thesetOrigin:: method is associated with the address of (the procedure that implements)setOrigin::

一个调度列表,这个表有一些词目,这些词目连接方法的选择器和指定类的方法的地址,方法setOrigin的选择器被联系setOrigin:的地址

 

40、When a new object is created, memory for it is allocated, and its instance variables are initialized. First among the object’s variables is a pointer to its class structure. This pointer, called isa, gives the object access to its class and, through the class, to all the classes it inherits from.

当一个新对象被创建的时候,给它的内存分配好,它的实例变量初始化,在对象的实例变量中第一个是指向它的类结构的指针,这个指针,叫做isa,会给这个对象接近它的类,然后通过这个类,接近它继承的所有的类。 

struct objc_class {

  Class isa OBJC_ISA_AVAILABILITY; //isa指针指向Meta Class,因为Objc的类的本身也是一个Object,为了处理这个关系,runtime就创造了Meta Class,当给类发送[NSObject alloc]这样消息时,实际上是把这个消息发给了Class Object

  #if !__OBJC2__

  Class super_class OBJC2_UNAVAILABLE; // 父类

  const char *name OBJC2_UNAVAILABLE; // 类名

  long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0

  long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识

  long instance_size OBJC2_UNAVAILABLE; // 该类的实例变量大小

  struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 该类的成员变量链表

  struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的链表

  struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存,对象接到一个消息会根据isa指针查找消息对象,这时会在method Lists中遍历,如果cache了,常用的方法调用时就能够提高调用的效率。

  struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表

  #endif

  } OBJC2_UNAVAILABLE;

《这个结构体来源一个博客:https://github.com/ChenYilong/iOSInterviewQuestions/blob/master/01%E3%80%8A%E6%8B%9B%E8%81%98%E4%B8%80%E4%B8%AA%E9%9D%A0%E8%B0%B1%E7%9A%84iOS%E3%80%8B%E9%9D%A2%E8%AF%95%E9%A2%98%E5%8F%82%E8%80%83%E7%AD%94%E6%A1%88/%E3%80%8A%E6%8B%9B%E8%81%98%E4%B8%80%E4%B8%AA%E9%9D%A0%E8%B0%B1%E7%9A%84iOS%E3%80%8B%E9%9D%A2%E8%AF%95%E9%A2%98%E5%8F%82%E8%80%83%E7%AD%94%E6%A1%88%EF%BC%88%E4%B8%8A%EF%BC%89.md#%E7%A1%AC%E4%BC%A4%E9%83%A8%E5%88%86

41、While not strictly a part of the language, the isa pointer is required for an object to work with the Objective-C runtime system. An object needs to be “equivalent” to a struct objc_object (defined in objc/objc.h) in whatever fields the structure defines. However, you rarely, if ever, need to create your own root object, and objects that inherit from NSObject or NSProxy automatically have the isa variable.AAAAAA

 

42、When a message is sent to an object, the messaging function follows the object’s isa pointer to the class structure where it looks up the method selector in the dispatch table

当一个信息发给一个对象的时候,这个消息函数沿着isa指针到类的结构,在那儿在那个调度列表中寻找方法选择器。

43、If it can’t find the selector there, objc_msgSend follows the pointer to the superclass and tries to find the selector in its dispatch table. 

如果它在那儿找到那个选择器,objc_msgSend 方法会沿着那个指针(类的指针,不是刚才那个isa)去父类并且尝试在它的调度序列中寻找那个selector(通过它再找到那个实现),

44、Successive failures cause objc_msgSend to climb the class hierarchy until it reaches the NSObject class. Once it locates the selector, the function calls the method entered in the table and passes it the receiving object’s data structure.

连续的失败会引起objc_msgSend会爬类的层次结构直达NSObject类,一旦定位了选择器,函数会调用进入列表中的方法,并且将收到的对象的数据源传给它。

45、This is the way that method implementations are chosen at runtime—or, in the jargon of object-oriented programming, that methods are dynamically bound to messages.

这是在运行时中方法实现的方式,或者用一种术语,面向对象编程,方法是动态地接近消息。

46、To speed the messaging process, the runtime system caches the selectors and addresses of methods as they are used.

为了加速消息处理,当他们用的时候,运行时系统缓存方法选择器和方法的地址。

47、There’s a separate cache for each class, and it can contain selectors for inherited methods as well as for methods defined in the class

对每一个类都有一个分开的缓存,它能包含继承的方法的选择器也包含定义在这个类里面的选择器。

48、Before searching the dispatch tables, the messaging routine first checks the cache of the receiving object’s class (on the theory that a method that was used once may likely be used again).

在搜寻调度列表前,消息程序首先接收对象类的缓存(理论上一个被用过一次的方法可能被再次使用)

49、 If the method selector is in the cache, messaging is only slightly slower than a function call

如果方法选择器在这个缓存,messaging方法只会比一个正常的函数调用慢一点。

50、Once a program has been running long enough to “warm up” its caches, almost all the messages it sends find a cached method. Caches grow dynamically to accommodate new messages as the program runs.

一旦一个项目跑了足够的长来温暖它的缓存,几乎所有的项目发送的消息都能找到一个缓存方法,当项目运行的时候缓存动态的增加来安排新的消息。

51、When objc_msgSend finds the procedure that implements a method, it calls the procedure and passes it all the arguments in the message. It also passes the procedure two hidden arguments:

  • The receiving object
  • The selector for the method

当objc_msgSend 方法找到了那个实现方法的程序后,它调用那个程序然后将在消息里的所有的参数传递给它,它也给这个程序传递两个隐藏的参数。

(1)接收的对象

 (2)方法的选择器

52、They’re said to be “hidden” because they aren’t declared in the source code that defines the method

他们(接收的对象和方法选择器)被说是被躲是因为他们没有在定义方法的源码中声明

53、They’re inserted into the implementation when the code is compiled.

当码编译的时候,他们被插进实现。

54、Although these arguments  aren’t explicitly declared, source code can still refer to them (just as it can refer to the receiving object’s instance variables). 

尽管这些参数是被清晰地声明,但是源码仍能指向它们(正如它(指源码)能指向接收对象的实例变量一样(注意,这不是传入的参数))

55、A method refers to the receiving object as self, and to its own selector as _cmd

一个方法指向接收的对象作为self.指向它的拥有的选择器作为_cmd

56、

In the example below, _cmd refers to the selector for the strange method and self to the object that receives a strange message.

- strange

 

{

 

    id  target = getTheReceiver();

 

    SEL method = getTheMethod();

 

 

 

    if ( target == self || method == _cmd )

 

        return nil;

 

    return [target performSelector:method];

 

}

57、self is the more useful of the two arguments. It is, in fact, the way the receiving object’s instance variables are made available to the method definition.

self是两个参数中最有用的,它是在事实上,通过那个方法(strange吧)接收对象的实例变量变化的方式变得可能

58、Get a method address

获取一个方法的地址

The only way to circumvent dynamic binding is to get the address of a method and call it directly as if it were a function

规避绑定的唯一方法是获取一个方法的地址然后直接当它是一个函数调用它

59、This might be appropriate on the rare occasions when a particular method will be performed many times in succession and you want to avoid the overhead of messaging each time the method is performed.

这在一些罕见的场合也许是合适的,当一个特殊的方法将被连续执行很多次的时候,你想要避免当每次这个方法被调的时候的过度开销。

60、The pointer that methodForSelector: returns must be carefully cast to the proper function type. Both return and argument types should be included in the cast.

methodForSelector方法返回的指针必须小心地铸造成合适的类型,返回和函数类型都应该包含在这个投射里。

61、void (*setter)(id, SEL, BOOL);

int i;

setter = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];

 

for ( i = 0 ; i < 1000 ; i++ )

setter(targetList[i], @selector(setFilled:), YES);

62、Using methodForSelector: to circumvent dynamic binding saves most of the time required by messaging. However, the savings will be significant only where a particular message is repeated many times, as in the for loop shown above.

尽量在循环中使用

63、This chapter describes how you can provide an implementation of a method dynamically.

这个章节动态的描述了一个方法的实现。

64、@dynamic propertyName

which tells the compiler that the methods associated with the property will be provided dynamically.

这个高速编译器,联系这个属性的方法将会动态的提供。

65、You can implement the methods resolveInstanceMethod: and resolveClassMethod: to dynamically provide an implementation for a given selector for an instance and class method respectively.

你能实现resolveInstanceMethod:resolveClassMethod: 这些方法来动态地分别提供为一个实例和类方法的选择器的实现

66、An Objective-C method is simply a C function that take at least two arguments—self and _cmd.

一个oc方法是一个至少包含两个参数的c功能,这两个参数是self和_cmd

67、You can add a function to a class as a method using the function class_addMethod. Therefore, given the following function:

 

void dynamicMethodIMP(id self, SEL _cmd) {

 

// implementation ....

 

}

上面的函数是oc方法的c转换你能给一个类增加一个函数通过class_addMethod方法

68、you can dynamically add it to a class as a method(called resolveThisMethodDynamically)using resolveInstanceMethod: like this:

@implementation MyClass

+ (BOOl)resolveInstanceMethod:(SEL)aSEL

{

    if (aSEL == @selector(resolveThisMethodDynamically)) {

     class_addMethod([self class], aSEL, (IMP)dynamicMethodIMP, “v@”);

     return YES;

    }

    return [super resolveInstanceMethod:aSEL]

}

69、Forwarding methods (as described in Message Forwarding) and dynamic method resolution are, largely, orthogonal. A class has the opportunity to dynamically resolve a method before the forwarding mechanism kicks in. If respondsToSelector: or instancesRespondToSelector: is invoked, the dynamic method resolver is given the opportunity to provide an IMP for the selector first. If you implement resolveInstanceMethod: but want particular selectors to actually be forwarded via the forwarding mechanism, you return NO for those selectors.AAAAA

70、An Objective-C program can load and link new classes and categories while it’s running. The new code is incorporated into the program and treated identically to classes and categories loaded at the start.

Oc项目在它运行的时候能加载和连接新的类和类目,新的码能被包含近项目中,能和最新加载的类和类目平等对待。

71、Dynamic loading can be used to do a lot of different things. For example, the various modules in the System Preferences application are dynamically loaded.

动态加载能被用于很多不同的方面,举例来说,在系统偏好应用中各种各样的模块被动态地加载。

72、In the Cocoa environment, dynamic loading is commonly used to allow applications to be customized. 

在Cocoa环境中,动态加载能允许应用被定制。

73、Others(动态加载的其他功能) can write modules that your program loads at runtime—much as Interface Builder loads custom palettes and the OS X System Preferences application loads custom preference modules

动态加载的其他功能能写在你的运行时中你的项目加载的模型,这跟IB加载定制的颜料以及OSX系统应该加载定制的偏好模型一样。

74、The loadable modules extend what your application can do. 

加载的模型延展应用的做的东西。

75、They contribute to it in ways that you permit but could not have anticipated or defined yourself. You provide the framework, but others provide the code. AAAAA

76、Although there is a runtime function that performs dynamic loading of Objective-C modules in Mach-O files (objc_loadModules, defined in objc/objc-load.h), Cocoa’s NSBundle class provides a significantly more convenient interface for dynamic loading—one that’s object-oriented and integrated with related services

虽然有运行时功能,它能完成oc模型的动态加载,但是Cocoa的NSBundle类为动态加载提供了一种自发意义更方便的的接口,那是面向对象的,集成了相关服务

77、Message forwarding(消息转发)

Sending a message to an object that does not handle that message is an error. However, before announcing the error, the runtime system gives the receiving object a second chance to handle the message.

发一个给一个对象消息,这个对象没有处理这条消息这会是一个错误,在发布错误之前,然后发布一个错误之前,运行时系统会给接收对象一个处理消息的机会。

78、If you send a message to an object that does not handle that message, before announcing an error the runtime sends the object a forwardInvocation: message with an NSInvocation object as its sole argument—the NSInvocationobject encapsulates the original message and the arguments that were passed with it.

如果你给一个对象发送消息,没有处理,在公告一个错误之前,运行时给这个对象发送一条用NSInvocation 对象作为唯一参数的的forwardInvocation消息,NSInvocation 对象封装了原始消息和参数,这些参数是通过NSInvocation传播的

79、You can implement a forwardInvocation: method to give a default response to the message, or to avoid the error in some other way. As its name implies, forwardInvocation: is commonly used to forward the message to another object.

你能实现forwardInvocation方法来给消息一个默认的回复,或者避免在一些方式的错误,正如他的名字显示,forwardInvocation 通常用来转发消息给另一个对象。

80、Take this a step further, and suppose that you want your object’s response to a negotiate message to be exactly the response implemented in another class.

更进一步,假想你想对negotiate方法的反应确确实实在另一个类中实现。

81、One way to accomplish this would be to make your class inherit the method from the other class. However, it might not be possible to arrange things this way. There may be good reasons why your class and the class that implements negotiate are in different branches of the inheritance hierarchy.

一种完成这个的方式是让你的类继承于其他类,然后,这么做可能不行,因为你的类和实现那个方法的类根本就在层级结构的一个不同的分支。

83、Moreover, it would be impossible to handle cases where you didn’t know, at the time you wrote the code, the full set of messages you might want to forward. That set might depend on events at runtime, and it might change as new methods and classes are implemented in the future. AAAAAA

84、The second chance offered by a forwardInvocation: message provides a less ad hoc solution to this problem, and one that’s dynamic rather than static

被forwardInvocation 消息提供的第二个机会提供了对这个问题的一个临时的方案,一个是动态的而不是静态的方案。

85、forward Invocation 中文意思:转发调用

86、However, NSObject’s version of the method simply invokes doesNotRecognizeSelector:. By overriding NSObject’s version and implementing your own, you can take advantage of the opportunity that the forwardInvocation:message provides to forward messages to other objects.

然而,那个方法的NSObject版本简单地唤起doesNotRecognizeSelector方法来覆盖NSObject的版本二实现你的版本,你能利用这个forwardInvocation提供的机会来转发信息给其他对象

86、

To forward a message, all a forwardInvocation: method needs to do is:

  • Determine where the message should go, and
  • Send it there with its original arguments.

 

为了转发消息,一个forwardInvocation方法需要做的是:

(1)决定消息将要去哪里

(2)用原始的参数发送去那儿

87、The message can be sent with the invokeWithTarget: method:

这条消息能用invokeWithTarget方法被发送

88、- (void)forwardInvocation:(NSInvocation *)anInvocation {

   if ([someOtherObject respondsToSelector:[anInvoction selector]])

     [anInvocation invokeWithTarget:someOtherObject];

  else

   [super forwardInvocation:anInvocation];

}

//接收的对象里面必须有这个方法

89、The return value of the message that’s forwarded is returned to the original sender

这条被转发的消息的返回值返回给原始的发送者

90、All types of return values can be delivered to the sender, including ids, structures, and double-precision floating-point numbers.

所有类型的返回值能被传递给发送者包括ids,structures,以及双精度的浮点型数字

91、A forwardInvocation: method can act as a distribution center for unrecognized messages, parceling them out to different receivers.

一个forwardInvocation方法能充当一个不识别消息的分发中心,将他们打包分发给不同的接收者

92、Or it can be a transfer station, sending all messages to the same destination.

或者它能是一个转运站,发送所有的消息往相同的目的地。

93、It can translate one message into another, or simply “swallow” some messages so there’s no response and no error.

它能传输一条信息进另一条,或者仅仅吞下一些信息,这样就会没有回复和错误。

94、 A forwardInvocation: method can also consolidate several messages into a single response.

一个forwardInvocation方法能加固几条信息为一个简单回复。

95、What forwardInvocation: does is up to the implementor AAAA

96、The forwardInvocation: method gets to handle messages only if they don’t invoke an existing method in the nominal receiver.

forwardInvocation方法能处理这些信息,只有在他们在正常的receiver里面没有唤起一个存在的方法。

97、Forwarding provides most of the features that you typically want from multiple inheritance. 

转发提供了你一般想要从多继承中的大多数特征

98、However, there’s an important difference between the two: Multiple inheritance combines different capabilities in a single object. It tends toward large, multifaceted objects.

然而,在这两者间有重要的不同,多继承将不同的功能联合进一个简单对象,它往往是对大的、多层面的对象。

99、Forwarding, on the other hand, assigns separate responsibilities to disparate objects. It decomposes problems into smaller objects, but associates those objects in a way that’s transparent to the message sender.

转发,它是将单独的责任赋值给不同的对象,它分解问题为很多小的对象,但是以一种方式将这些对象关联起来,这种方式对消息发送者是清晰地。

100、Forwarding not only mimics multiple inheritance, it also makes it possible to develop lightweight objects that represent or “cover” more substantial objects. 转发不仅模仿多继承,it也让开发代表或者覆盖更多大量的轻量级的对象成为可能。

101、The surrogate stands in for the other object and funnels messages to it. AAAAA

102、The proxy is such a surrogate

proxy就是这样的一个代理

103、A proxy takes care of the administrative details of forwarding messages to a remote receiver, making sure argument values are copied and retrieved across the connection, and so on.

代理照顾好转发消息的管理细节给一个远程的接收者,确保参数值在连接中被拷贝和被取回。

104、But it doesn’t attempt to do much else; it doesn’t duplicate the functionality of the remote object but simply gives the remote object a local address, a place where it can receive messages in another application.

但是它没有尝试做额外的更多,它也没有复制远程函数的功能,仅仅给了远程函数一个本地的地址,一个你能在另外应用中收信息的地方。

105、In this circumstance, you could initially create, not the full-fledged object, but a lightweight surrogate for it.

在这个例子中,你最初创建的不是一个丰满的对象,而是那个对象的轻量级的代理。

106、This object could do some things on its own, such as answer questions about the data, but mostly it would just hold a place for the larger object and, when the time came, forward messages to it

这个代理对象也能自己做一些事情,例如回答数据的问题,但是大部分时候它仅仅为更大对象持有一个地方而已,当时间到了时候,将消息传递给更大的对象。

107、When the surrogate’s forwardInvocation: method first receives a message destined for the other object, it would ensure that the object existed and would create it if it didn’t

当代理forwardInvocation方法第一次收到去往另一个对象的消息时,它将确保这个对象存在,如果不存在,这个代理就创建它。

108、 All messages for the larger object go through the surrogate, so, as far as the rest of the program is concerned, the surrogate and the larger object would be the same.

所有的给更大对象的消息穿过代理,至于程序的其他而言,代理和更大的对象是相同的。

109、Forwarding and Inheritance

if ( [aWarrior respondsToSelector:@selector(negotiate)] )

In many cases, NO is the right answer. But it may not be. If you use forwarding to set up a surrogate object or to extend the capabilities of a class, the forwarding mechanism should probably be as transparent as inheritance.

许多情况下,No是正确的答案,但是也许也不是,如果你运用转发来设置一个代理对象或者延展了一个类的能力,转发装置应该像继承一样透明。

110、If you want your objects to act as if they truly inherited the behavior of the objects they forward messages to, you’ll need to re-implement the respondsToSelector: and isKindOfClass: methods to include your forwarding algorithm:

如果你想要你的对象充当好像他们真正的继承了那些对象(你发消息的对象)的行为,你需要实现这些方法来包含你的转发算法。

111、

- (BOOL)respondsToSelector:(SEL)aSelector

 

{

 

    if ( [super respondsToSelector:aSelector] )

 

        return YES;

 

    else {

 

        /* Here, test whether the aSelector message can     *

         * be forwarded to another object and whether that  *

 

 * object can respond to it. Return YES if it can.  */

    }

 

    return NO;

 

}

 

//这里,测试这个selector消息能否被转发给另一个对象,并且是否这个对象能反应它,如果能返回yes.

112、instancesRespondToSelector:

Returns a Boolean value that indicates whether instances of the receiver are capable of responding to a given selector.

返回一个bool值,显示接收者的实例是否有能力反应一个被给的选择器

113、

if an object forwards any remote messages it receives, it should have a version of methodSignatureForSelector: that can return accurate descriptions of the methods that ultimately respond to the forwarded messages; for example, if an object is able to forward a message to its surrogate, you would implement methodSignatureForSelector: as follows:

如果一个对象转发自己收到的任何信息,它应该有一个methodSignatureForSelector方法的版本,这个方法会返回旧方法的描述,这些方法是反应被转发的信息的

114、

- (NSMethodSignature*)methodSignatureForSelector:(SEL)selector

 

{

 

    NSMethodSignature* signature = [super methodSignatureForSelector:selector];

 

    if (!signature) {

 

       signature = [surrogate methodSignatureForSelector:selector];

 

    }

 

    return signature;

 

}

115、This (转发)is an advanced technique, suitable only for situations where no other solution is possible. It is not intended as a replacement for inheritance. If you must make use of this technique, make sure you fully understand the behavior of the class doing the forwarding and the class you’re forwarding to.

这是一项有用的技术,适合没有其他解决方案能行的情况下,它不想代替继承,如果你必须用这个技术,确保你完全理解了转发方和接收方的类的行为。

116、In computer science, run time, runtime or execution time is the time during which a program is running (executing), in contrast to other program lifecycle phases such as compile time, link time and load time.

在计算机科学,运行时或者执行时是一个项目执行的时间,对比其他的程序生命循环短语:编译时间,连接时间,加载时间。等

Type Encodings

117、To assist the runtime system, the compiler encodes the return and argument types for each method in a character string and associates the string with the method selector.

为了帮助运行时系统,这个编译器对每个方法的返回和参数类型进行编码,以一种字符的方式,并且连接这个字符用方法选择器。

118、The coding scheme it uses is also useful in other contexts and so is made publicly available with the @encode() compiler directive.

它用的编码方案在其他上下文也是有用的,所以用@encode()编译器指令,这是公开可行的。

119、When given a type specification, @encode() returns a string encoding that type. 

当指定一个类型,@encode()返回一个编译那个类型的字符串。

120、The type can be a basic type such as an int, a pointer, a tagged structure or union, or a class name—any type, in fact, that can be used as an argument to the C sizeof() operator.

这个类型能成为一个基本类型,像int,指针,一个标记的结构或者union,或者一个类的名字,事实上任何可以作为sizeof()运算符参数的类型。

121、char *buf1 = @encode (int **)

      char *buf2 = @encode(struct key)

    char *buf3 = @encode(Rectangle)

122、The table below lists the type codes. Note that many of them overlap with the codes you use when encoding an object for purposes of archiving or distribution. 

以下的表格列举了类型的码,注意当对一个对象进行编码时,他们中的许多重叠了你使用的码,这是为了存档或者分发的目的。

123、However, there are codes listed here that you can’t use when writing a coder, and there are codes that you may want to use when writing a coder that aren’t generated by @encode().

然而,有一些码列举自那儿,当写一个coder的时候,你不能用的;有一些你想要用的码不能通过@encode()方法产生

124、Objective-C does not support the long double type. @encode(long double) returns d, which is the same encoding as for double.

OC语言不支持long double 类型,@encode (long doubel) 返回d,这是和double 相同的类型。

125、Objects are treated like structures. For example, passing the NSObject class name to @encode() yields this encoding:

{NSObject=#}

对象当做结构对待

Declared Propertie

参考文章:http://zhangbuhuai.com/understanding-objective-c-runtime-part-3/


第二次学习

参考链接:

1、https://www.jianshu.com/p/103963dfd35c

2、https://www.jianshu.com/p/adf0d566c887

1、objc_object

objc_object是表示一个类的实例的结构体

struct objc_object {

   Class isa OBJC_ISA_AVALABILITY;

};

typedef struct objc_object *id

可以看到,这个结构体只有一个字体,即指向其类的isa指针。这样,当我们向一个Objective-C对象发送消息时,运行时库会根据

实例对象的isa指针找到这个实例对象所属的类。Runtime库会在类

的方法列表及父类的方法列表中去寻找与消息对应的selector指向

的方法,找到后即运行这个方法。

2、meta-class是一个类对象的类

3、在上面我们提到,所有的类自身也是一个对象,我们可以向这个对象发送消息(即调用类方法)

4、既然是对象,

5、方法的selector用于表示运行时方法的名字。Objective-C在编译时,会依据每一个方法的名字、参数序列,生成一个唯一的整形标识(int 类型的地址),这个标识就是SEL。SEL可以理解为其实就是一个类型。

6、两个类之间,只要方法名相同,那么方法的SEL就是一样的,每一个方法都对应着一个SEL。所以在Objective-C同一个类(及类的继承体系)中,不能存在2个同名的方法,即使参数类型不同也不行

7、当然,不同的类可以拥有相同的selector,这个没有问题。不同类的实例对象执行相同的selector时,会在各自的方法列表中去根据selector去寻找自己对应的IMP。

8、通过下面三种方法可以获取SEL:

a、sel_registerName函数

b、Objective-C编译器提供的@selector()

c、NSSelectorFromString()方法

9、IMP实际上是一个函数指针,指向方法实现的地址。

第一个参数:是指向self的指针(如果是实例方法,则是类实例的内存地址;如果是类方法,则是指向元类的指针)

第二个参数:是方法选择器(selector)

接下来的参数:方法的参数列表。

第二次学习:(官方开放文档)

1、runtime: https://opensource.apple.com/tarballs/objc4/    最重要的文档

2、runloop:https://opensource.apple.com/tarballs/CF/

3、gcd         https://github.com/apple/swift-corelibs-libdispatch

4、GNU libc  https://www.gnu.org/software/libc/  https://ftp.gnu.org/gnu/libc/

5、malloc     http://www.opensource.apple.com/source/libmalloc

6、GNUstep    http://www.gnustep.org/resources/downloads.php

7、以上链接摘自:https://www.jianshu.com/p/53629acf89b9

8、https://blog.csdn.net/weixin_34417635/article/details/86930971

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值