runtime - Method详细笔记

Runtime中Method详细介绍

1.找到它,认识它

//*> 在objc/runtime.h中定义了Method类型,Method是一个objc_method结构体指针,结构体中包含SEL、IMP这两种类型,下面做介绍

/// An opaque type that represents a method in a class definition.
typedef struct objc_method *Method;

struct objc_method {
    SEL method_name
    char *method_types
    IMP method_imp
}   

//*> SEL 和 IMP 类型分别在objc/objc.h定义了

/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;  //!> objc_selector结构体详细声明没有在objc/objc.h中查到~~waht?

/// A pointer to the function of a method implementation. 我粗糙的翻译:方法执行的函数指针~~么么哒
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ );
#else
typedef id (*IMP)(id, SEL, ...);
#endif

2.SEL粗来

/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;

SEL官方定义的是selector的指针,也就是选择器地址。测试代码(ViewController.m)


- (void)viewDidLoad {
    [super viewDidLoad];

    SEL sell = @selector(viewDidLoad);
    NSLog(@"%p  %s",sell,__FUNCTION__);
    NSLog(@"%p  %s",_cmd,__FUNCTION__);
}

/*
打印结果:
2016-03-25 13:48:23.660 runtimeStudy2[5392:3259595] 0x1090a04d5  -[ViewController viewDidLoad]
2016-03-25 13:48:23.661 runtimeStudy2[5392:3259595] 0x1090a04d5  -[ViewController viewDidLoad]

说明:
1.SEL确实是指针,是一个Selector选择器的指针;
2.SEL是一个唯一的标识,例如:0x1090a04d5;
2._cmd为当前方法的SEL;
*/

//*> 需要补充的是,只要方法名一样,生成的SEL也是一样,道理你们懂得,起名字嘛,必须是一样,例如上面的那个:0x1090a04d5,还是解释一下为啥都是一样的吧,因为SEL的名字是根据方法名字进行生成的,跟在那个类或者其他的都没有关系,下面是证据:
/*
创建继承NSObject的三个类:Person、Son和Daughter,分别在他们的.m文件中写入:
+ (void)load
{
    NSLog(@"%p %s",_cmd,__FUNCTION__);
}

然后运行程序,打印结果:
2016-03-25 15:25:14.915 测试1[6093:3790055] 0x10d9cdff3 +[Son load]
2016-03-25 15:25:14.915 测试1[6093:3790055] 0x10d9cdff3 +[People load]
2016-03-25 15:25:14.915 测试1[6093:3790055] 0x10d9cdff3 +[Daughter load]

SEL是一样的。
*/

3.IMP也粗来见见吧

typedef id (IMP)(id, SEL, ...); 前面那个宏不太了解啥意思,但是可以确定的是,我们应该用的是下面这个声明,typedef id(*IMP)(id,SEL,...),可能是因为void*是C++哪里的熟客,而id是objc_object类型是oc的熟客,whatever?

  • IMP是函数指针,看它的定义就知道了,需要一个id,SEL,还有其他。id是objc_object类型,如果想要了解它,看我写的下篇 — 类,对象。
  • Objective-C程序通过Method中的IMP准确的执行id的SEL。高效~,比Runtime中消息传递快捷。

4.Method姗姗来迟

Method是类中的方法,####1####中表明了SEL、IMP等组成了Method的结构,SEL是x,IMP是y,x->y的映射,通过id和SEL就可以找到对应的IMP,然后执行实现的代码。

5.想要用你做点事

主要就是窥探一下objc/message.h,顺便说一下,为啥用message命名呢,呵呵达~~

//*> 1.Runtime发送消息,这个东西好玩,看大部分博客几乎都是从它讲起~~,其实可以看看官方的注释:
/**
 * Sends a message with a simple return value to an instance of a class.   发送SEL和返回值(id)给接受者self(id类型)。
 *
 * @param self A pointer to the instance of the class that is to receive the message.  self是对象指针,它来接收消息,What is objc_Object?
 * @param op The selector of the method that handles the message.    op是SEL小家伙(顺便说一句,有了SEL和self是不是就可以找到IMP咯)
 * @param ...
 *   A variable argument list containing the arguments to the method.    一些参数~~么么哒
 *
 * @return The return value of the method.  返回值,id类型的
 */
id objc_msgSend(id self, SEL op, ...)
/*略...*/
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)

//*> 最关键的就是动态创建一个Method,嗨起来O(∩_∩)O
/// Defines a method
struct objc_method_description {
    SEL name;               /**< The name of the method */
    char *types;            /**< The types of the method arguments */
};

上一篇:帝国cms伪静态设置方法(收藏)


下一篇:ASP.NET 实现伪静态网页方法