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

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


相关推荐
热门推荐
  • 微软回应《消费者报告》:Surface用几年都不会坏

    腾讯科技讯 据外媒报道,权威杂志《消费者报告》(Consumer Reports)报告称,25%的微软Surface设备在两年内就会出问题。微软回应称,它的Surface设备的稳定性要比这份报告中的结果高得多。《消费者报告》近日称,由于微软......

    2017-08-13 03:20:46

    分享
  • 独家对话锤子投资人郑刚:我为什么要炮轰阿里巴巴

    关键时刻,第一时间送达!首发 / 腾讯深网(ID:qqshenwang)文 / 王潘划重点:1、阿里本来都说同意投资,过桥贷款本来会给结果也没给,导致锤子差点没缓过来,一度发不出工资。2、贾跃亭在和锤子谈合作时,当时.........

    2017-08-12 07:41:23

    分享
  • 对话锤子投资人:我为何要炮轰阿里?

    从左至右分别为罗永浩、唐岩、郑刚文/ 腾讯科技 王潘锤子科技CEO罗永浩近日在极客公园活动上宣布,锤子目前已经获得了10亿元人民币融资。锤子科技早期投资人、紫辉创投创始合伙人郑刚随后在微信朋友圈转发锤子融资的文章,并对阿里巴巴展开了猛烈的炮......

    2017-08-10 18:23:00

    分享
  • 报告:酒后找代驾渐成消费习惯 去年订单超2.53亿单

    活动现场。中新网 吴涛 摄中新网北京8月8日电(吴涛)8日,在北京发布的一份白皮书显示,“酒后找代驾”已经成为一种新的消费习惯,代驾使交通事故一年减少350万起。8日,“创新与责任助力可持续发展研讨会”在北京举行。研讨会上,清华大学法学院公......

    2017-08-10 18:36:44

    分享
  • 陆奇透露为何微软Cortana不及亚马逊Alexa

    The Verge中文站 8月14日报道今年早些时候,微软高管陆奇转投百度。在供职于微软期间,陆奇将很多时间用于Cortana语音助手和微软的聊天机器人平台,同时还负责必应搜索和Office团队。在近期接受《连线》杂志采访时,陆奇罕见地发表......

    2017-08-15 14:15:19

    分享
  • 人人网原负责人许朝军的“前半生”

    2005年到2009年,在许朝军负责人人网期间,该产品成为最火热的社交网络平台。2017年6月15日,北京市公安局治安管理总队收到群众举报,在北京东城区一家茶楼内有人开设德州扑克赌局,连同许朝军在内的9人正在进行赌博。一个半月后,7月29日......

    2017-07-31 13:56:41

    分享
  • 手机QQ里的注册那些事儿

    QQ作为一个连接人、内容与生活的社交平台,其注册帐号将是我们产品中非常重要的一环。基于Mobile端与Pc端的区别,我们在手机版QQ的设计上要求更轻、更快、更便捷的给用户下发QQ号。目前手机版QQ的用户量覆盖率已.........

    2017-08-13 04:58:32

    分享
  • C4D彻底火了,有人学会后工资翻了50%…

    兄弟们,姐妹们别来无恙前几天逛站酷看招聘信息的时候发现有的电商公司,已经把C4D也列为求职者的加分项。电商行业这几年变化非常快,不光是运营维度上,视觉方面也是年年翻新,两三年前C4D刚开始在电商设计上运.........

    2017-08-10 23:52:59

    分享
  • 摩拜上演大范围解锁故障 业内称因其App软件架构不佳

    “技术控”之“痛”摩拜上演大范围解锁故障郭梦仪一直以“技术控”为标签的摩拜单车近日突然出现大规模无法开锁的情况,在早高峰时间上演大瘫痪。8月10日上午,大量网友在社交网络上反映,北京、南京、上海等多地的摩拜单车在开锁环节遭遇卡壳,一些网友连......

    2017-08-13 13:37:25

    分享
  • 首汽约车布局海外市场 推出国际用车服务

    文/腾讯科技 相欣网约车下半场争夺战已经从中国市场转移到境外市场。首汽约车今日宣布推出国际用车产品,包括接送机和包车服务(半日租、日租、多日租),旨在以“小交通”为切入口,串联海外出行的大交通市场。据了解,首汽约车推出的国际用车服务采取的是......

    2017-08-15 23:10:54

    分享
  • 云集微店公众号被封了!

    你还等什么呢? 昨日,云集的两个官方公众号云集微店官方、云集服务号被封了! 显示【该公众号因违规无法关注】,所有功能停止使用,可能是永久封禁!8月1日,“环球捕手”因涉嫌违规刚被封不到10日.........

    2017-08-13 22:45:30

    分享
  • 乐视发工资了 乐视控股员工:是6月的工资

    每经记者张斯每经编辑贾运可实习编辑方芳8月10日19:00,乐视控股内部员工向《每日经济新闻》记者表示,“刚刚发了一个月工资,但还有一个月没发。”当日下午,有媒体报道称,本周二贾跃亭抵达香港筹措到第一笔资金,解决了非上市体系员工7月10日缓......

    2017-08-11 05:18:40

    分享
  • 高铁上也能用超高速WiFi:比4G网络快10倍!

    展示该技术的列车是北京南站发往天津的C2027次列车,乘客可以通过手机连接到指定WiFi,可稳定、流畅的上网和观看视频,由于移动终端的性能限制,所以实际体验和家中WiFi基本没有区别,远超过在列车上使用4G网络.........

    2017-08-13 09:14:36

    分享
  • Android手机里最安全的黑莓KEYone国行版开箱评测

    消沉10年再次强势回归?没错,黑莓回归中国市场了!莓粉激动万分,今天小编终于拿到了黑莓最新款BlackBerry KEYone的纯黑色国行版,到手发现纯黑的机身果然高端大气有特色。首先,这次的国行KEYone承袭了黑莓一.........

    2017-08-13 22:43:12

    分享
  • 英国要求厂商严格一些 保护联网汽车免遭黑客攻击

    英国要求厂商严格一些 保护联网汽车免遭黑客攻击,黑客攻击 汽车 英国政府 无人驾驶汽车......

    2017-08-07 13:38:32

    分享
  • 腾讯控股:“一杯敬明天,一杯敬过往”

    "投资银行在线"是一个资本与项目对接的互联网金融平台,围绕“早期投资、私募股权融资、项目并购退出”提供一站式金融服务。如果您有靠谱的项目,请将商业计划书发送到: bp@pelist.com。这是笔者从腾讯视频微博.........

    2017-08-12 19:58:12

    分享
  • 同样做海外投资,为什么郭广昌能全身而退?

    01今年3月3日,央视《遇见大咖》的节目播出了一个片段,郭广昌、王健林、马云、董明珠共同参加了一个活动。郭广昌登台演讲:刚才王健林董事长跟我说,在中国开会最难的事是什么,是座次、是排名。政府排名还比较.........

    2017-08-13 05:02:55

    分享
  • 又一条产品线砍掉了 微软手环2出现同步问题

    原标题:又一条产品线砍掉了微软手环2出现同步问题中关村在线消息:早在2016年10月份,微软手环2就已经被官方下架。而传闻中基于物联网的微软手环3也因为开发遭遇瓶颈,团队已经解散。一直到现在再没有关于新的微软手环开发进度的消息。已经基本可以......

    2017-08-07 08:26:37

    分享
  • 势不可挡 比特币价格突破4000美元

    比特币凤凰科技讯 据科技博客TechCrunch北京时间8月14日报道,上周日,比特币经历了不同寻常的一天。 就在24小时前,比特币的价格还不到3700美元。但是一个小时前,比特币价格飙升到了4000美元以上,而且没有停止的迹象。现在,比特......

    2017-08-14 13:44:25

    分享
  • 六月全球最赚钱十大手游出炉 王者荣耀无悬念霸榜

    新浪美股讯北京时间8月16日凌晨消息,根据美国市场研究公司Superdata的数据,全球手机游戏市场总规模将在2017年达到1050亿元人民币。Superdata估计,中国游戏王者荣耀是全球手游界最赚钱的游戏,仅6月份营收就可能达到1.5亿......

    2017-08-16 04:50:14

    分享
换一换
AD