导航:首页 > 安装方法 > ios类方法放在哪里

ios类方法放在哪里

发布时间:2023-01-10 11:11:50

Ⅰ iOS 之OC对象的分类

 1)instance对象----实例对象

    instance对象就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象。

    instance对象中包含了:

        * isa指针

        * 成员变量的值    

2)class对象----类对象

    每个类在内存中只有一个类对象。可通过三种方法获得:

        1.实例对象调用class方法(Class c1 = [a class])   

        2.类调用class方法(Class c2 = [Animal class])

        3.使用object_getClass方法获取(Class c3 = object_getClass(a))

    class对象中包含了:

        * isa指针

        * superclass指针

        * 类的属性信息(@property)

        * 类的对象方法信息(instance method)

        * 类的协议信息(protocol)

        * 类的成员变量信息(ivar)

3)meta-class对象----元类对象

    每个类内存中只有一个元类对象。可通过以下的方法获取:

     Class metaCls = object_getClass([NSObject class]);

    元类对象和类对象的内存结构是一样的,但用途不一样,元类对象中包含了:

        * isa指针

        * superclass指针

        * 类的类方法信息(class method)

从上面的知识我们就可以就看出来:

   1. 成员变量具体的值,放在instance对象(实例对象)里。

    2. 属性信息、对象方法信息、协议信息、成员变量信息,放在Class对象(类对象)里。

    3. 类方法信息,放在meta-class对象(元类对象)里。

根据信息的存放,我们可以得到 对象方法存储在class的内存里,类方法存在于meta-class内存里 。

       那么问题来了,假如现在有一个Animal类的实例化对象a1,如果想用a1调用Animal类的对象方法animalMethod该如何调用呢?毕竟,a1是存储在实例化对象instance内存中的,而animalMethod方法是存储于Animal类的内存中的。

       实际上instance实例的对象的isa指针指向class,找到class类以后,再在class类中找存储于其中的对象方法方法进行调用。

       调用类方法的过程也是如此,class类通过其内部的isa指针找到meta-class类中存储的类方法,然后再进行调用。

isa、superclass 总结

下面是一张广为流传关于isa、superclass的经典图。

isa

    instance的isa指向class

    class的isa指向meta-class

    meta-class的isa指向基类的meta-class

superclass

    class的superclass指向父类的class

    如果没有父类,superclass指针为nil

    meta-class的superclass指向父类的meta-class

    基类的meta-class的superclass指向基类的class

instance 调用对象方法的轨迹

    isa找到class,方法不存在,就通过superclass找父类。

class 调用类方法的轨迹

    isa找meta-class方法不存在,就通过superclass找父类。

Ⅱ iOS对象方法和类方法的区别与调用方式

1、类方法是属于整个类,而不属于某个对象。2、类方法只能访问类成员变量,不能访问实例变量,而实例方法可以访问类成员变量和实例变量。3、类方法的调用可以通过类名.类方法和对象.类方法,而实例方法只能通过对象.实例方法访问。4、类方法只能访问类方法,而实例方法可以访问类方法和实例方法。5类方法不能被覆盖,实例方法可以被覆盖。

Ⅲ iOS中元类和类

元类和类的数据结构是同一个,只是运行时使用的字段不一样。

实例方法调用是通过objc_msgSend来调用,它的第一个入参就是实例对象,其流程是查找实例对象的isa指针,找到类对象,然后找到method_t的IMP,bl直接跳转调用。

类方法的调用和实例方法调用一致,它的第一个入参对象是类对象,类对象的isa指向的是元类。

所以,没有元类的话,类方法是没有办法调用的。objc_msgSend的调用流程是一定要isa指针的。

如果实例方法和类方法都放在类对象上,那类对象的isa指针只能指向自己了,那一旦类方法和实例方法重名,就没法搞了!

Ⅳ iOS分类中调用主类原实例、类方法

看到里面有一个 struct objc_method_list ** methodLists ,这就是存储该类所有方法的地方了。查找方法的时候并不是每次都去遍历methodList的,而是先去cache中查,cache中存储了最近常用的方法。

看一下objc_method_list这个结构体

它有一个指向存储废弃方法列表的指针struct objc_method_list *obsolete,还有方法的个数int method_count,还有一个用于存储方法的数组struct objc_method method_list[1]。其中数组的长度是可变的。

看一下objc_method这个结构体,

SEL method_name表示方法名,char *method_types表示参数及返回值类型,IMP method_imp表示指向方法实现的指针。

导入:

协议方法的获取

类属性的获取

实例方法的获取

类方法的获取

方法交换 method swizzled

Ⅳ ios 怎么在类方法中 调用类方法

类方法和实例方法 实例方法是— 类开头是+ 实例方法是用实例对象访问,类方法的对象是类而不是实例,通常创建对象或者工具类。 在实例方法里,根据继承原理发送消息给self和super其实都是发送给self 在类方法里面self是其他的类的类方法

Ⅵ 第五篇:IOS类探究(成员变量值放在哪里,成员变量信息放在哪里)

我们简单写个demo,在我们定义的类HPWPerson里放了name,age属性,还有_hobby成员变量

首先我们考虑两个问题,类方法是放在哪里?成员变量是放在哪里?带着这两个问题我们进行深入的探究下。

我们通过上篇结尾的分析其实知道,实例方法,成员属性,协议等都是存放在class_rw_t这个结构体里,如下面源码所示,

我们继续在class_rw_t结构体源码里找下,发现有class_ro_t这个结构体,这个结构体是干什么的呢?

我们通过打印得到如下:

@property (nonatomic ,) NSString *name;这个会生成下划线的成员变量_name,
@property (nonatomic ,assign) int age;这个会生成下划线的成员变量_age,
发现我们再打印class_ro_t里发现有上图所示的成员变量,所以其中“_hobby”,“_age”,"_name"这些是存在class_ro_t这个结构里的。

通过上面我们发现,成员变量的值是放在对象里,成名变量名字以及一些大小信息放在类里面,这个是为什么呢?其实类里面的结构体它就好比一个模板,通过这个模板就可以生成各个成员变量信息,但是成员变量的值是不同的所以成员变量的值要存放在实例对象里,成员变量名及大小信息放在类里面就可以。

接着我们再继续探究下,在class_rw_t这个结构体里有class_ro_t这个结构体,那这两个结构体有什么关系呢?

1.class_ro_t是在编译的时候生成的(只读),是一个纯净的空间,不能被修改的

我们知道苹果的runtime可以动态的修改属性和方法,但是ro里又不支持修改的,那它是如何实现的呢?
我们先看下WWDC里的一个视频讲解:
WWDC讲解ro,rw链接

通过上面的视频我们知道,ro在编译的时候生成,在内存不够的时候就会进行移除,当要使用的时候就会重新从磁盘里去加载。在objc源码里我们发现有个叫class_rw_ext_t的结构体,简称为rwe。class_rw_ext_t这个也不是每个类里都生成的,因为生成class_rw_ext_t是有条件的:或者有分类,或者runtime API修改的时候会生成这个rwe结构体。runtime是无法修改成员变量的,rwe在对ro里进行拷贝出的也是其中一部分,一般ro里也就10%的内容需要修改。接着我们看rwe源码如下,也验证了我们这点:如果有rwe就直接返回里面的methods,没有就返回ro里的baseMethods。

属性存放在rw里源码:如果有rwe就直接返回里面的properties,没有就返回ro里的baseProperties。

协议存放在rw里源码:如果有rwe就直接返回里面的protocols,没有就返回ro里的baseProtocols。

设计元类只是单独为了存放我们的类方法吗?

其实其目的是为了复用消息机制。在OC中调⽤⽅法,其实是在给某个对象发送某条消息。
消息的发送在编译的时候编译器就会把⽅法转换为objc_msgSend这个函数。
id objc_msgSend(id self, SEL op, ...) 这个函数有俩个隐式的参数:消息的接收者,消息的⽅法
名。通过这俩个参数就能去找到对应⽅法的实现。
objc_msgSend函数就会通过第⼀个参数消息的接收者的isa指针,找到对应的类,如果我们是通过
实例对象调⽤⽅法,那么这个isa指针就会找到实例对象的类对象,如果是类对象,就会找到类对
象的元类对象,然后再通过SEL⽅法名找到对应的imp,然后就能找到⽅法对应的实现。
那如果没有元类的话,那这个objc_msgSend⽅法还得多加俩个参数,⼀个参数⽤来判断这个⽅法
到底是类⽅法还是实例⽅法。⼀个参数⽤来判断消息的接受者到底是类对象还是实例对象。
消息的发送,越快越好。那如果没有元类,在objc_msgSend内部就会有有很多的判断,就会影响
消息的发送效率。
所以元类的出现就解决了这个问题,让各类各司其职,实例对象就⼲存储属性值的事,类对象存储
实例⽅法列表,元类对象存储类⽅法列表,符合设计原则中的单⼀职责,⽽且忽略了对对象类型的
判断和⽅法类型的判断可以⼤⼤的提升消息发送的效率,并且在不同种类的⽅法⾛的都是同⼀套流
程,在之后的维护上也⼤⼤节约了成本。
所以这个元类的出现,最⼤的好处就是能够复⽤消息传递这套机制。不管你是什么类型的⽅法,都
是同⼀套流程。

接着我们如何证明我们上面所说的呢?下面我们来看下在源码里设置断点调试:

首先我们打开objc的源码,

我们一直按上面去打印,最后会打印一个classMethod这个类方法,在我们设置HPWPerson这个类里也有这个方法,如下,所以证明了类方法是存放在元类里面的。

接着我们看些runtime的api方法的实现:

上面这些我们是用runtime的api把成员变量,实例方法,类方法等打印出来。
通过上面总结:
1)ro里存放成员变量,实例方法,属性,协议,类对象
2)类方法存放在元类里面

Ⅶ ios 怎么调用分类里面的方法

ios category类别的使用
Objective-C提供了一个非常灵活的类(Class)扩展机制-类别(Category)。类别用于对一个已经存在的类添加方法(Methods)。你只需要知道这个类的公开接口,不需要知道类的源代码。需要注意的是,类别不能为已存在的类添加实例变量(Instance Variables)。

类别的基本语法如下:
@interface ClassName(CategoryName)
//method declarations
@end
@interface 类名(类别名)
类别方法申明
@end
注意几点:
1.现有类的类名位于 @interface之后
2.括号中是类别的名称(只要名称唯一,可以添加任意多的类别)
3.类别没有实例变量部分
类别的语法与类的语法非常相似。类别的方法就是类的方法。类别的定义可以放在一个单独的文件中("类别名.h"), 也可以放在一个已存在的类的定义文件中(.h文件)。类别的实现则可放在一个单独的“类别名.m”文件中,或另一个类的实现文件中。这点也与类的定义相似。因为类别的方法就是类的方法,所以类别的方法可以自由引用类的实例变量(无论公有或私有)。

子类(subclassing)是进行类扩展的另一种常用方法。与子类相比,类别最主要的优点是:系统中已经存在的类可以不需修改就可使用类别的扩展功能。例如,假设系统中存在一个类A;另外一个类B中定义了一个类A类型的实例变量,并包含了类A的头文件“#import <A.h>"。假设一段时间后,需要对类A扩展几个新的方法。如果用子类,就需要创建一个子类A-1。如果类B想要使用类A的新方法,就要进行如下修改:1) 将包含的头文件改为"#import<A-1.h>"; 2)将所有用到的类A对象改为类A-1的对象。可以想象,如何有很多类需要用到类A的新功能(比如类A是iOS中的类UIViewController),随着系统的升级(iOS从1.0到5.0),你的程序需要不停地进行这种繁琐地修改。如果使用类别,即使类A升级了,系统中其它的类可以不需任何修改,直接就可以调用类A的新方法。

类别的第二大优点是实现了功能的局部化封装。类别定义可以放在一个已存在的类(类A)的定义文件中(.h)。这意味着这个类别只有在类A被引用的前提下才会被外部看到。如果另一个类(类B)不需要用到类A的功能(没有包含类A的.h文件),也就不会看到依附类A存在的类别。iOS SDK中广泛运用这种类别定义法来封装功能。例如,在 UINavigationController.h中定义了专为UINavigationController扩展的UIViewController类别:

@interface UIViewController (UINavigationControllerItem)
@property(nonatomic,readonly,retain) UINavigationItem *navigationItem;
@property(nonatomic,readonly,retain) UINavigationController *navigationController;
......
@end
如果一个类不引用UINavigationController.h,也就不会看到navigationItem和navigationController这两个性质申明(declared property)。

类别的另一个优点是轻巧(light-weight)。很多时候,对已存在的类所需的扩展仅仅是几个新方法。这时,用类别避免了在系统中留下很多非常短小的“微”子类,使程序更加紧凑。

归纳:
1、实现类别
同实现类相似,实现方法即可
2、 类别的局限性
1.类别不能添加新的实例变量
2.命名冲突,如果类别中方法和类中已有方法同名,则类别具有更高优先级
3 类别的作用
1.将类的实现分散到多个不同文件或多个不同框架中
2.创建私有方法的前向引用
3.向对象添加非正式协议
4 利用类别分散实现
利用类别可以将类的方法分散到多个源文件中
特别指出的是:类别可以访问其继承的类的实例变量
在使用一个方法时,对象的方法是在接口中声明、父类中声明、还是类别中声明并不重要
类别不仅可以分散实现到不同源文件,也可跨框架
5、 使用类别创建前向引用
虽然可以实现未声明的方法,但是编译器会提出警告
通过类别可以提供声明,而且,声明的方法不必要一定在类别的实现中实现,也可以在类的实现中实现
6、 非正式协议和委托类别
委托(delegage)是一种对象,另一个类的对象会要求委托对象执行它的某些操作
委托对象接受其它对象对它的特定方法的调用
其实就是委托对象必须实现别的对象调用的方法,与接口类似
7、 ITunesFinder项目
8 、委托和类别
委托和类别有什么关系?委托强调类别的另一种应用:被发送给委托对象的方法可以声明为一个NSObject的类别
创建一个NSObject的类别称为“创建一个非正式协议”
9、 响应选择器
选择器只是一个方法名称,可以使用@selector()预编译指令指定选择器,其中方法名位于圆括号中,但它以OC运行时使用的特殊方式编码,以快速执行查询
NSObject提供了一个respondsToSelector的方法,询问对象以确定其是否实现某个特定消息
10、 选择器的其他应用
选择器可以被传递,可以作为方法参数,甚至可以作为实例变量存储

Ⅷ iOS中 类方法和实例方法及self和super

1、类方法 :Class Method 有时被称为静态方法,类方法可以独立于实例对象而执行。在使用类方法时要注意以下几点:

2、实例方法: 必须由类的实例对象调用,可以访问属性,实例变量,同样可以访问类对象,使用限制相对于类方法较少。

总的来说: self 会优先调用本类中的方法, super 会优先调用父类方法。但是, self 是指向本类的指针,是类的隐藏参数,指向当前调用方法的对象(类对象或者实例对象), super 却不是指向父类的指针,只是一个编译器标识符,其在运行时中与self相同,指向 同一个消息接受者 ,只是 self 会优先在当前类的methodLists中查找方法,而 super 则是优先从父类中查找, 向super发送消息是一种调用继承链上的超类定义的 方法实现 的方法。

结果分析:

经过上面的例子再回来看self和super的实现原理可能更加好理解:

这样结合上述例子和self和super的原理就会很容易明白为什么 [self class] 和 [super class] 输出结果会是一样的,同时在 BaseViewController 的 viewDidLoad 中 [self class] 和 [super class] 输出都是子类类对象了

iOS中关于类方法和实例方法及self和super

Ⅸ ios怎样调用类方法

类方法也叫工厂方法,一般用加号“+”修饰
不需要创建对象就直接可以使用,直接使用类名久可以调用,例如:[NSString stringWithFormat:@"%@",@"123"];

阅读全文

与ios类方法放在哪里相关的资料

热点内容
小孩的数学教学方法 浏览:368
怎么备份系统的方法 浏览:580
三钩的使用方法图 浏览:833
塞纳小桌板安装方法 浏览:955
柠檬草茶的功效与作用及食用方法 浏览:331
个税计算方法地区 浏览:144
吉列剃须刀使用方法 浏览:875
如何解释命运的方法 浏览:918
肩肌训练方法 浏览:396
2052除以57的简单方法 浏览:74
胸软筋挫伤治疗方法 浏览:392
烤猪肉的简单腌制方法 浏览:341
大腿外侧冷的原因和解决方法 浏览:51
ddc桩工程计算方法 浏览:689
指针万用表使用方法图解 浏览:372
差热分析最佳方法 浏览:631
收被子方法视频 浏览:123
记忆宫殿方法如何训练的坏处 浏览:58
材料进场验收的基本方法有哪些 浏览:382
惠普后视镜安装方法 浏览:402