ios-收集一些自认为有用的小知识

什么情况使用 weak 关键字,相比 assign 有什么不同?


什么情况使用 weak 关键字?


在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决,比如: delegate 代理属性


自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用 weak,自定义 IBOutlet 控件属性一般也使用 weak;当然,也可以使用strong。


不同点:


weak 此特质表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似, 然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。 而 assign 的“设置方法”只会执行针对“纯量类型” (scalar type,例如 CGFloat 或 NSlnteger 等)的简单赋值操作。


assign 可以用非 OC 对象,而 weak 必须用于 OC 对象


怎么用 copy 关键字?


用途:


NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;

block 也经常使用 copy 关键字

block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.在 ARC 中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效。你也许会感觉我这种做法有些怪异,不需要写依然写。


copy 此特质所表达的所属关系与 strong 类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为 NSString 时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个 NSMutableString 类的实例。这个类是 NSString 的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。


用 @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。


@property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的


@property 的本质是什么?


@property = ivar + getter + setter;


下面解释下:


“属性” (property)有两大概念:ivar(实例变量)、存取方法(access method = getter + setter)。


“属性” (property)作为 Objective-C 的一项特性,主要的作用就在于封装对象中的数据。 Objective-C 对象通常会把其所需要的数据保存为各种实例变量。实例变量一般通过“存取方法”(access method)来访问。其中,“获取方法” (getter)用于读取变量值,而“设置方法” (setter)用于写入变量值。这个概念已经定型,并且经由“属性”这一特性而成为 Objective-C 2.0 的一部分。 而在正规的 Objective-C 编码风格中,存取方法有着严格的命名规范。 正因为有了这种严格的命名规范,所以 Objective-C 这门语言才能根据名称自动创建出存取方法。其实也可以把属性当做一种关键字,其表示:

编译器会自动写出一套存取方法,用以访问给定类型中具有给定名称的变量。 所以你也可以这么说:


@property = getter + setter;


例如下面这个类:


@interface Person : NSObject

@property NSString *firstName;

@property NSString *lastName;

@end


上述代码写出来的类与下面这种写法等效:


@interface Person : NSObject

- (NSString *)firstName;

- (void)setFirstName:(NSString *)firstName;

- (NSString *)lastName;

- (void)setLastName:(NSString *)lastName;

@end


更新:


property在runtime中是objc_property_t


定义如下:


typedef struct objc_property *objc_property_t;


而objc_property是一个结构体,包括name和attributes,定义如下:


struct property_t { const char *name; const char *attributes;};


而attributes本质是objc_property_attribute_t,定义了property的一些属性,定义如下:


/// Defines a property attribute

typedef struct { 

const char *name; 

/**< The name of the attribute */

 const char *value;

 /**< The value of the attribute (usually empty) */

objc_property_attribute_t;


而attributes的具体内容是什么呢?其实,包括:类型,原子性,内存语义和对应的实例变量。


例如:我们定义一个string的property


@property (nonatomic, copy) NSString *string;


通过


property_getAttributes(property)


获取到attributes并打印出来之后的结果为


T@"NSString",C,N,V_string


其中T就代表类型,C就代表Copy,N代表nonatomic,V就代表对于的实例变量。


ivar、getter、setter 是如何生成并添加到这个类中的?


“自动合成”( autosynthesis)


完成属性定义后,编译器会自动编写访问这些属性所需的方法,此过程叫做“自动合成”(autosynthesis)。需要强调的是,这个过程由编译 器在编译期执行,所以编辑器里看不到这些“合成方法”(synthesized method)的源代码。除了生成方法代码 getter、setter 之外,编译器还要自动向类中添加适当类型的实例变量,并且在属性名前面加下划线,以此作为实例变量的名字。在前例中,会生成两个实例变量,其名称分别为 _firstName与 _lastName。也可以在类的实现代码里通过@synthesize语法来指定实例变量的名字.


@implementation  Person

@synthesize firstName = _myFirstName;

@synthesize lastName = _myLastName;

@end


大致生成了五个东西


OBJC_IVAR_$类名$属性名称:该属性的“偏移量” (offset),这个偏移量是“硬编码” (hardcode),表示该变量距离存放对象的内存区域的起始地址有多远。

setter 与 getter 方法对应的实现函数

ivar_list:成员变量列表

method_list:方法列表

prop_list:属性列表


也就是说我们每次在增加一个属性,系统都会在 ivar_list

中添加一个成员变量的描述,在 method_list

中增加 setter 与 getter 方法的描述,在属性列表中增加一个属性的描述,然后计算该属性在对象中的偏移量,然后给出 setter 与 getter 方法对应的实现,在 setter 方法中从偏移量的位置开始赋值,在 getter 方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转.


@protocol 和 category 中如何使用 @property


1.在 protocol 中使用 property 只会生成 setter 和 getter 方法声明,我们使用属性的目的,是希望遵守我协议的对象能实现该属性


2.category 使用 @property 也是只会生成 setter 和 getter 方法的声明,如果我们真的需要给 category 增加属性的实现,需要借助于运行时的两个函数:


3.objc_setAssociatedObject


4.objc_getAssociatedObject


runtime 如何实现 weak 属性


runtime 对注册的类, 会进行布局,对于 weak 对象会放入一个 hash 表中。 用 weak 指向的对象内存地址作为 key,当此对象的引用计数为0的时候会 dealloc,假如 weak 指向的对象内存地址是a,那么就会以a为键, 在这个 weak 表中搜索,找到所有以a为键的 weak 对象,从而设置为 nil。


@property中有哪些属性关键字?/ @property 后面可以有哪些修饰符?


属性可以拥有的特质分为四类:


原子性--- nonatomic 特质


在默认情况下,由编译器合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备 nonatomic 特质,则不使用自旋锁。请注意,尽管没有名为“atomic”的特质(如果某属性不具备 nonatomic 特质,那它就是“原子的” ( atomic) ),但是仍然可以在属性特质中写明这一点,编译器不会报错。若是自己定义存取方法,那么就应该遵从与属性特质相符的原子性。


读/写权限---readwrite(读写)、readonly (只读)


内存管理语义---assign、strong、 weak、unsafe_unretained、copy


方法名---getter=<name> 、setter=<name>


getter=<name>的样式:


   @property (nonatomic, getter=isOn) BOOL on;


setter=这种不常用,也不推荐使用。故不在这里给出写法。)


setter=<name>一般用在特殊的情境下,比如:


在数据反序列化、转模型的过程中,服务器返回的字段如果以 init 开头,所以你需要定义一个 init 开头的属性,但默认生成的 setter 与 getter 方法也会以 init 开头,而编译器会把所有以 init 开头的方法当成初始化方法,而初始化方法只能返回 self 类型,因此编译器会报错。


这时你就可以使用下面的方式来避免编译器报错:


@property(nonatomic, strong, getter=p_initBy,setter=setP_initBy:)NSString *initBy;


另外也可以用关键字进行特殊说明,来避免编译器报错:


@property(nonatomic, readwrite, copy, null_resettable) NSString *initBy;


- (NSString *)initBy __attribute__((objc_method_family(none)));


不常用的:nonnull,null_resettable,nullable


注意:很多人会认为如果属性具备 nonatomic 特质,则不使用 “同步锁”。其实在属性设置方法中使用的是自旋锁


一周精选

iOS 通俗易懂的HTTP网络

今日头条:819CVP系列开发者沙龙将在月球上举行

国内的老程序员最后都去哪了?

如何成为一个高逼格的程序员指南

从简书iOS客户端,来谈谈Hybrid方案细节设计

懒人做iOS系列之jenkins+git+fir打包


CocoaChina

全球最大苹果开发中文社区


相关推荐
热门推荐
  • 那个写从前慢的木心,究竟是个什么样的人?

    来源:听明明吹牛皮(niupimingming) 作者:牛皮明明2001年,《上海文学》,刊发木心的《上海赋》。作家陈村一读,立马给跪了:“我这辈子读过无数中文,结识许多作家。毫不夸张地说,木心先生的文章,在我见.........

    2017-09-29 17:50:17

    分享
  • 中国大飞机,造出自己的“心脏”到底有多难

    中国大飞机,造出自己的“心脏”到底有多难,发动机 中国大飞机 航空发动机 波音......

    2017-09-29 17:20:36

    分享
  • iPhone 8/8Plus评测:你真的甘心笑着扮演X的配角?

    9月12日,Steve Jobs Theater地下,库克早早甩出了「One more thing」大招。iPhone X横空出世,史称"iPhone 8配角惨案"。毫无疑问,十周年的苹果秋季发布会,iPhone X......

    2017-09-25 00:25:33

    分享
  • 广汽三菱张跃赛:下一个五年将深化“SUV+新能源”战略

    10月12日晚,广汽三菱将在总部长沙举办五周年庆典活动。2017年前三个季度,广汽三菱实现了累计销量8.13万辆,同比增长达199%的骄人成绩。这样的成绩,不仅为广汽三菱冲击年销量目标奠定基础,也给企业未来发展注.........

    2017-10-12 21:09:33

    分享
  • 小空间大规划,满足三代人居住

    追求创新,拥抱变化--这里是「设计创变」点击关注 设计创变 回复1 获得20套家装施工图空间之中融入微轻工业风特质;用色彩点出空间韵味,大面牆壁使用灰色水泥底漆而天花板则选择白色去呈现,并与线性轨道灯,拉.........

    2017-09-29 17:49:31

    分享
  • 把家装修成这样,还有谁愿意出门?

    想了解装修心得和免费设计,就点我吧!以下这些看似不经意的家居设计,却处处隐藏着小惊喜!如果家里这么装,谁还想出门呢?两个旋转的家具,瞬间把一个大客厅。三五朋友聚会的小客厅。需要加班的时候,派上用场.........

    2017-09-29 17:50:04

    分享
  • 吊顶已经过时了,这才是2017年的真时尚!

    有经验的人都知道,现在的单元房房高大多在两米八以下,面对这一现实,你还坚持吊顶吗?▲像这样一幅泰山压顶的样子这就是你想要的吗?对于两米八的房高来说,吊顶真的已经过时了,但是如果不吊顶,你是不是就只.........

    2017-09-26 17:00:59

    分享
  • 新买的花盆处理一下再用,要不会害死你的花!

      养花可以说是一件非常有益的事情,不但能够修身养性还能够丰富我们的业余生活,还赏心悦目。不过养花也是需要有讲究的,平时很多地方可能大家都不太在意,其实养花也是需要从细节入手这样才能够养好,今天跟.........

    2017-10-16 20:06:58

    分享
  • 一根毛线就能种花,美到邻居都羡慕!

    我的花草王国想养漂亮的花儿,关注我,教你这样做。关注谁家还把植物放阳台上养现在流行将花搬进家里只用一根毛线打造完美绿植惊艳整个家居空间!植物背景墙▼家里绿植总是摆在墙角或窗台一点都不美观新颖不如用.........

    2017-09-29 17:49:26

    分享
  • 咳嗽吃这个,一天就见效!你却把它当垃圾丢了!

    用茄子把煮水喝能治咳嗽?赶紧看看!(视频来源于网络)没想到茄子把还有这样的用途~茄子全身都是宝不光能止咳,还有这么多神奇的功效····赶快来看!茄 子 全 身 都 是 宝茄子是夏秋常吃的蔬菜了,但你却想.........

    2017-10-12 21:13:00

    分享
  • 提醒丨近期准备去加油站的司机们注意了!请提前做好准备……

    开车的朋友们注意了,10月15日至28日北京市停止自助加油。近日,北京市安监局发布通告,部署近期本市危险化学品和烟花爆竹的管理措施。通告要求10月15日至28日期间,北京市危险化学品生产企业、加油站、油库、构.........

    2017-10-12 21:09:39

    分享
  • 衣服不管染上什么,用这招都能洗掉,太实用了!

    新买的衣服沾上了酱汁?裤子被溅到果汁?赶紧学起来,一招就能洗掉它们!白 醋白衬衫的领口最容易发黄,用洗衣粉也搓不干净。还有些放在衣柜久了,拿出来有一股旧颜色。和洗衣液一起,倒入一小杯白醋,静置15分.........

    2017-10-16 20:06:54

    分享
  • 摩拜、ofo合并传闻背后:共享单车步入精细化运营

    王丽娜合并的故事还在上演,解决用户出行“最后一公里”难题的共享单车行业恐怕也不例外。10月3日,据彭博报道,摩拜和ofo投资者正在洽商合并,以结束烧钱竞争。报道称,相关谈判还处于初级阶段,合并后估值可能会超过40亿美元。ofo公关部门相关负......

    2017-10-14 09:37:27

    分享
  • 红枣和它一起泡,每天一杯,7天身体内湿气消,脸色更红润!

    俗话说:“一日三颗枣,青春不显老”。红枣除了有健康长寿功能外,里边高含量的维生素,能有效的为女性美容养颜,让女性肌肤白净,有杰出的美容效果。红枣含有的营养成分特别丰富,具有的养生功效与作用更是惊人.........

    2017-10-16 20:06:58

    分享
  • 华尔街日报:为什么说iPhone 8遇冷反而可能对苹果有利

    上海苹果零售店工作人员向顾客解释iPhone 8 Plus凤凰科技讯 据《华尔街日报》北京时间9月23日报道,当新款iPhone上市时,它通常都会快速销售一空。然而,在iPhone 8和iPhone 8 Plus从周五开始发售后,已经有迹象......

    2017-09-24 01:43:10

    分享
  • 东北零下20度也能安全越冬的植物,养成小盆栽特讨人喜欢

    踏踏实实养花,勤勤恳恳种花长按左侧二维码识别关注 开启你的养花之旅很多朋友问我有没有适合在东北露地越冬的植物,而且不能是那些长得太大的乔木或灌木,要长得比较小的,还能养成盆栽的,那么矾根就是不二之.........

    2017-09-26 17:00:40

    分享
  • 传台湾某公司主控SSD藏后门,银监会要求调查

    传台湾某公司主控SSD藏后门,银监会要求调查,银监会 新浪 固态硬盘 微博......

    2017-10-02 23:12:41

    分享
  • 160㎡美式复式楼装修案例,客厅吊顶很是精致迷人!

    今天小编来和大家分享一个160平米复式的装修案例,房子的风格定位为美式。在整个屋子当中,客厅的吊顶装饰的很精致很迷人,一起来欣赏下吧~客厅布置得很井井有条。家具、柜子都选用了实木的,价格相对昂贵但是环.........

    2017-10-14 10:03:57

    分享
  • 吹风机对着厨房墙壁吹一下,奇迹出现了,赶快告诉您的家人!

    清理厨房墙壁上的油污 家里的墙壁上老是有油污去不掉,怎么办?吹风机就是一个便捷有效的去除油污的方法,没必要专门买清洁剂,超方便~!把吹风机在有油污的地方吹一吹,用加热档,将油污加热到一定温度,然后边.........

    2017-10-16 20:06:52

    分享
  • 嫌弃座椅不舒服,旧枕头来帮你!赶紧get!

    教你种花养花方法教你养这些植物,不仅好打理,还能驱蚊净化空气。关注天天贴脸睡的枕头一旦睡塌了或变形了不但会因为螨虫导致脸上长痘还会危害脊椎健康但是这么大个枕头扔了怪可惜其实这样改一改比新枕头还好用.........

    2017-10-16 20:06:59

    分享
换一换
AD