Objective-C(一) - 类与对象

今天讲的是OC语言相关类的东西,基础语法那些就不讲了,讲下他的特别的地方。
也是根据印象写的,难免有所纰漏,希望大家指正


Objective-C.png

关键字部分:


assign : 主要用于修饰基本数据类型,简单赋值,不更改引用计数。修饰的对象释放后,指针的地址依旧存在,会造成野指针。在堆上容易造成崩溃。栈上的内存系统会自动处理。(关于堆栈会在内存管理章节详细说这一块,可以简单理解为因为基本数据类型分配在栈中即可)

retain : MRC中使用。释放旧值,保留新值,并增加新值的引用计数。

strong :用于修饰强引用的属性,释放旧的对象,将旧的对象的值赋予新的对象,并使引用计数+1

weak :相当于assign,用于修饰弱引用的属性,与assign不同的地方是,weak会在对象消失的时候自动把指针置为nil.不会增加引用计数

copy :建立一个索引计数为1的对象,然后释放旧的对象,一个对象发生变化不影响另一个对象。(copy只是浅复制,只复制指针地址,不会开辟新的内存空间

@dynamic : 告诉编译器不自动生成setter getter方法

@synthesize :如果属性没有手动实现setter和getter方法,编译器会自动加上这两个方法

nonatomic :禁止多线程,变量保护,提高性能。它比atomic快,但也是线程不安全的。

atomic : 修饰的对象会保证 setter 和 getter 的完整性,任何线程对其访问都可以得到一个完整的初始化后的对象。它比nonatomic安全,但不是绝对的线程安全,如多个线程调用set和get方法会导致获得的对象值不同。绝对的线程安全可以用同步锁@synchronizd.

类与对象


数据结构

1.Class

 struct objc_class {
       struct objc_class *isa; // isa指针
       struct objc_class *super_class; // 父类指针
       const char *name; //类名
       long version; //版本信息,默认为0
       long info; // 类信息,供运行时使用的位标识
       long instance_size; //该类的实例变量大小
       struct objc_ivar_list *ivars; // 该类的成员变量链表
#if defined(Release3CompatibilityBuild)
      struct objc_method_list *methods;        // 方法定义的链表
#else
      struct objc_method_list **methodLists; // 方法定义的链表
#endif
      struct objc_cache *cache;                      // 方法缓存
      struct objc_protocol_list *protocols;      // 协议链表
 }

重点介绍下几个属性

  1. isa指针: 在oc中所有类对象本身也是一个对象,这个对象的Class里面也有一个isa指针指向metaClass。
  2. super_class:指向该类的父类,如果是最顶层的根类(NSObject或NSProxy),则super_class为NULL.(tip:之后会讲讲NSProxy的应用场景)。
  3. cache: 用于方法列表的缓存。

2.object

  struct objc-object {
     Class isa ;
  }
  typedef struct objc_object *id;

isa 指针指向object的类,当某个对象调用消息时,会通过该对象的isa指针找到这个实例对象的类,在类的方法列表及父类的方法列表中查找。
当创建一个实例对象时,分配的内存包含了一个objc_object数据结构,然后是类的实例变量的数据。NSObject类的alloc和allocWithZone:方法会调用class_creatInstance来创建objc_object数据结构。

3.cache

  struct objc_cache {
    unsigned int mask;
    unsigned int occupied;
    Method buckets[1]; 
  }
  • mask: 当前能达到的最大的index(从0开始),所以缓存的size(total)是mask+1
  • occupied:指定实际占用的缓存bucket的总数。因为cache是以散列表的形式存在的,所以会有空槽,occupied表示当前被占用的数目。
  • buckets: 指向method数据结构指针的数组。这个数组可能包含不超过mask+1个元素。需要注意的是指针可能是NULL,表示该缓存bucket没有被占用,另外占用的bucket可能是不连续的,这个数组会随着时间增长。

常见区分

4. id 与 NSObjct*
id: typedef struct objc_object *id , id 本质上是一个指向结构体struct_object的指针。关于这个对象的消息,编译器需要到运行时才会确定,所以编译器不会判断对这个对象调用的消息进行判断。
NSObjcet: 编译器会确切知道了该类的所有消息,向该对象发送NSObject没有声明的消息的时候编译器会报错。

5.id与instancetype
instancetype:使方法的返回类型为所在类的类型。
id和instancetype的区别

  • id在编译期无法判断对象的真实类型
  • instancetype返回的对象调用方法时编译器会进行类型检查,如果赋值给其他对象会报警告
  • id可以用来定义变量,也可以作为返回值,形参,instancetype只能用于返回值

6.实例对象,类对象以及他们的isa指针以及meta-class:

  • 实例对象objc_object的isa指针指向objc_class
  • 类对象 objc_class的isa指针指向自身的meta-class
  • meta-class的isa指针指向NSObject的meta-class,NSObject的meta-class指向自身

7. [self class] [super class]调用分析:
查看class的调用:

- (Class)class{
      return objcet_getClass(self);
}

super调用方法时实质是调用:

objc_msgSendSuper(struct objc_super * _Nonull super, SEL _Nonnull op, ...)

可知super是一个指向 objc_super结构体 的指针

查看objc_super

objc_super

objc_msgSendSuper函数可转换为:

  objc_msgSendSuper((objc_super){(id)self,(id)class_getSuperClass(objc_getClass(self))},op)

显然receiver就是实例对象,super_class为self的父类。所以调用super的时候传递的对象也就是receiver为self。
所以 NSStringFromClass([self class]) 和NSStringFromClass([super class]) 返回的值是一样的。

面试相关

  • 一个OC对象占用多少内存
    系统分配了16个字节给NSObject对象(通过malloc_size函数获得),但NSObject对象内部只使用了8个字节的空间(64位环境下,通过class_getInstanceSize获得)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352

推荐阅读更多精彩内容