iOS-对象间的传值

iOS - 对象间传值

传值方式

个人把他们分为官方和非官方,可以看出官方版的传值方式均为两个对象之间通过系统特定的方法来进行数据传递,而非官方版则是通过一个中间件来进行数据传递

官方版:

① delegate 代理
② block 代码块
③ NSNotification 通知
④ KVC 键-值编码
⑤ KVO 键值观察模式
⑥ 属性直接传值

非官方版:

① 单例类
② 数据缓存(如 NSUserDefaults 不推荐)

delegate

它是一种设计模式,代理者通过实现被代理这定义的代理协议,来进行通信传递消息,在iOS中主要用于视图与使用这个视图的对象之间来进行交互,可以有返回值
注意:delegateblock都是一对一的关系 他们和通知不一样 通知是一对多 delegate设置属性是用assignweak修饰 不要改变其引用计数 避免和代理者之间出现循环引用

block

概念: Block是一个C级别的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是其运行需要编译器和运行时支持,可作为参数进行传递用于回调,block 可以定义在方法里,函数不能。block 语法简单,写在方法里可以访问局部变量可以使代码更加的紧凑,结构化。相对于 delegateblock 不用建立代理协议,使用简单,它的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息。从ios4.0开始就很好的支持Block

用途:常用于逆向传值、作为方法参数、作为类的属性、作为全局变量

注意:

1、在使用block前需要对block指针做判空处理。不判空直接使用,一旦指针为空直接产生崩溃。

2、在block使用时为什么要用copy修饰 因为block变量默认是声明为栈变量的 block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈上的,而不是在堆上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。因为栈区的特点就是创建的对象随时可能被销毁,一旦被销毁后续再次调用空对象就可能会造成程序崩溃,在对block进行copy后,block存放在堆区.

3、使用方将self或成员变量加入block之前要先将self变为weakSelf 如果不是self引用的block则不需要 比如数组枚举遍历的block

4、在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析构。

意义:Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C语言的扩展,用来实现匿名函数的特性。它允许开发者在两个对象之间将任意的语句当做数据进行传递,往往这要比引用定义在别处的函数直观,

NSnotification

概念:NSnotification 一个中心对象注册和发送通知,所用的其他的对象都可以收到通知。
用途:常常用于在向服务器端请求数据或者提交数据的场景,在和服务器端成功交互后,需要处理服务器端返回的数据,或发送响应消息等
注意:它是同步的消息通知机制,只有Observer将消息处理完毕后,消息发送者才会继续执行,因此在通知处理的地方做大量耗时操作的话,就会带来卡顿的问题啦。

在多线程的应用中,Notification在哪个线程中Post, 就是在那个线程分发,也就在同一个线程中被observer处理。而通常呢,我们会在Observer对象的dealloc方法中去removeObserver,理论上,如果observerdealloc和消息发送者的postNotification的方法在不同的线程中调用的话,是有可能会导致Crash的。

意义:广播数据,一对多

KVC

概念:Key-value coding,它是一种使用字符串标识符,一个非正式的 Protocol,间接访问对象属性的机制,而不是直接调用gettersetter方法是通过 set value for key 进行间接访问实例变量。

用途:动态访问你要存取的类的属性、动态访问和修改私有变量

注意:可以1对1,也可以1对多。
意义:提供一种机制来间接访问对象的属性

KVO

概念:KVO,被观察者添加观察者,被观察者使用KVC键值编码来修饰它的实例变量,当被观察者发生改变时,观察者就能侦听到被观察者改变的事件,从而做出相应。

注意:

  1. addObserver之后,在不需要监听时,及时remove,否则被监听对象释放后,再触发监听器会引起crash
  2. addObserver方法与removeObserver方法要一一对应。不要重复添加监听,也不要remove没有添加过的监听。

用途:对指定对象的某个属性进行观察,当属性发生变化时,进行通知.

意义:提供了一种当其它对象属性被修改的时候能通知当前对象的机制

单例模式

单例模式大概是设计模式中最简单的一个,没什么好说的,就是保证一个类只有一个实例,并且提供一个全局的访问入口访问这个实例。正式因为它的这个特性,我们可以通过他来作为一个中间件来进行传值(其实也不算是传值,类似于前边对象set 后边对象get)原理跟缓存到本地沙盒基本相同。

注意:单例虽好 但也有坑

1、多线程
异步多线程的时候,假如同时执行到创建的那一行,这时候可能会创建多个不同的对象,所以这里可以加锁或同步块,但这不是OC创建单例最高效的方式,有一种性能是他几十倍的方法就是使用dispatch_once,关于性能的比对,大神们做过实验和分析。请参考这里

2、内存问题
单例模式实际上延长了对象的生命周期。那么就存在内存问题。因为这个对象在程序的整个生命都存在。所以当这个单例比较大的时候,总是hold住那么多内存,就需要考虑这件事了。另外,可能单例本身并不大,但是它如果强引用了另外的比较大的对象,也算是一个问题。别的对象因为单例对象不释放而不释放。

当然这个问题也有一定的办法。比如对于一些可以重新加载的对象,在需要的时候加载,用完之后,单例对象就不再强引用,从而把原先hold住的对象释放掉。下次需要再加载回来。

3、循环依赖
在开发过程中,单例对象可能有一些属性,一般会放在init的时候创建和初始化。这样,比如如果单例A的m属性依赖于单例B,单例B的属性n依赖于单例A,初始化的时候就会出现死循环依赖。死在dispatch_once里。

数据缓存

iOS本地缓存数据方式有五种:
1、直接写文件方式:可以存储的对象有NSString、NSArray、NSDictionary、NSData、NSNumber,数据全部存放在一个属性列表文件(*.plist文件)中。

2、NSUserDefaults(偏好设置),用来存储应用设置信息,文件放在perference目录下。

3、归档操作(NSkeyedArchiver),不同于前面两种,它可以把自定义对象存放在文件中。

4、coreData:coreData是苹果官方iOS5之后推出的综合型数据库,其使用了ORM(Object Relational Mapping)对象关系映射技术,将对象转换成数据,存储在本地数据库中。coreData为了提高效率,甚至将数据存储在不同的数据库中,且在使用的时候将本地数据放到内存中使得访问速度更快。我们可以选择coreData的数据存储方式,包括sqlite、xml等格式。但也正是coreData 是完全面向对象的,其在执行效率上比不上原生的数据库。除此之外,coreData拥有数据验证、undo等其他功能,在功能上是几种持久化方案最多的。

5、FMDB:FMDB是iOS平台的SQLite数据库框架,FMDB以OC的方式封装了SQLite的C语言API,使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码,对比苹果自带的Core Data框架,更加轻量级和灵活,提供了多线程安全的数据库操作方法,有效地防止数据混乱。

总结:数据缓存这里就不过多赘述了,但无论使用哪种方式进行缓存存取,道理是相同的,请参考单例传值,不过如果仅仅是对象之间的传值,强烈不建议使用缓存!!!总而言之,传值方式要根据场景自己来定,了解各种方式才可以更好的帮你完成对象间值的传递。

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

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,362评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • OC语言基础 1.类与对象 类方法 OC的类方法只有2种:静态方法和实例方法两种 在OC中,只要方法声明在@int...
    奇异果好补阅读 4,268评论 0 11
  • 这两天下雪了, 天气转冷。上周末感冒了,眼球疼痛,连带着头也阵阵作痛。吃了药,这周接近痊愈了,眼睛还是很难受,总是...
    yjding阅读 213评论 0 1
  • #幸福是需要修出来的~每天进步1%~幸福实修08班~04-姜群-富阳# 20170818(61/99) 【幸福三朵...
    呼哈二姐阅读 165评论 1 1