设计模式

设计模式

1.delegate和notification什么区别,什么情况使用?

2.描述一下KVO和KVC。

Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者。

KVC是KeyValue Coding的简称,它是一种可以直接通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。

3简述NotificationCenter、KVC、KVO、Delegate?并说明它们之间的区别?

答:消息中心,消息通知;

利用键-值间接访问类中的某个属性

利用键-路径间接访问类中的某个属性,也称观察者模式

代理,多用于两个类之间的传值

15.你熟悉的设计模式有哪些,请说说对他们的理解。

答:单例,通知,KVO,代理,target-action等

单例,主要特点是一个类只有一个对象。对外提供了一个获取唯一对象的方法,一般都是类方法,完整的单例会重写很多引用计数相关的方法(比如:allocWithZone,copyWithZone,retain,release,autorelease,retainCount等)以保证对象在任何情况下都唯一。单例最大的价值就是建立程序级别的全局变量,就是把不同模块都要用的变量以属性的形式放到单例里面,以便随时使用。音频播放类程序一般会写单例来管理需要播放的音乐信息,需要下载的地方也会以单例的形式来管理下载对象。

通知,是M与C通信的方式之一。一般是Model发送变化的时候,会发送通知告诉Controller,Controller再做相应的处理。需要先往通知中心里面注册观察者,然后在合适的时机,通知中心post通知,观察者做对应的处理,当观察者将要释放的时候,从通知中心移除观察者。

KVO,也是M与C通讯的方式。一般是C去观察M的某个属性,某个属性发生变化之后,C做出相应的处理,当C将要释放的时候,M移除观察者。

代理,是V与C通信的方式之一。一般C是V的代理,V发生变化的时候,C做对应的调整。例如:UITableView被点击了,由Controller做处理。我们在自己写代理的时候,一定要清楚谁来处理事件,谁来调用代理方法。通常情况下都是C处理时间,V在适当的时候调用代理方法。

target-action,也是V与C通信的方式之一。一般C是V的target,V被点击或者被滑动之后,C做出对应的处理。无论是target-action还是代理,核心都是回调。

8.在使用系统的一些类例如UITableView时,会发现其delegate属性的语义设置为assign而不是retain,为什么呢?

答:delegate的语义修饰符 为assign不是retain主要是为了避免两个对象因相互引用造成的内存泄露问题。

因为retain修饰delegate,当通过set方法赋值时,对象的引用计数会+1.

如果此时两个对象具有如下关系:A对象有一个属性是B,B的delegate是A。即互相为彼此的属性。例如:A是viewController,B是tableView.  B是A的属性,B的引用计数会+1,B的delegate是A,A的引用计数也会+1.那么如果A没有释放,B就一直不会释放,因为A对B有拥有权。 同理,B没有释放,A也一直释放不掉,因为B对A也有拥有权。 因此A和B的dealloc都会不执行,造成内存泄露.

代码演示如下(只写出了核心代码):

A *a =  [[A alloc] init] // a引用计数:1

B *b =  [[B alloc] init] // b引用计数:1

a.b = b; // b引用计数:2

b.delegate = a; // a引用计数:2

[a release]; // a引用计数:1

[b release]; // b引用计数:1

//最终A和B都释放不掉。

assign则是直接赋值,并不会引起引用计数增加,因此使用assign不会出现内存泄露。

代码演示如下(只写出了核心代码):

A *a =  [[A alloc] init] // a引用计数:1

B *b =  [[B alloc] init] // b引用计数:1

a.b = b; // b引用计数:2

b.delegate = a; // a引用计数:1

[a release]; // a引用计数:0,b引用计数:1(在a的dealloc里面_b被释放了)

[b release]; // b引用计数:0

//最终A和B都可以释放掉。

13.NSNotification和KVO的区别和用法是什么?什么时候应该使用通知,什么时候应该使用KVO,它们的实现上有什么区别?

答:通知和KVO都是观察者模式的体现,二者侧重点有些不同。

通知往往用于1对多的场景,多个观察者观察一个通知,一旦这个通知被通知中心post,所有观察者都可以做出响应。具体的实现流程是:(1)通知中心通过addObserver方法添加观察者,其实是把观察者和通知进行绑定,多次使用addObserver方法可以为同一个通知添加多个观察者。(2)通知中心发送通知。(3)各个观察者做各自的处理。(4)在观察者销毁之前(dealloc中),从通知中心移除观察者。

KVO多用于1对1的场景,一个对象去观察另外一个对象的属性值有没有发生变化,一旦发生变化,观察者做出响应。具体的流程是:(1)被观察者添加观察者,指定观察者观察的属性。(2)被观察者的属性在某一时间发生了变化。(3)观察者做出响应。(4)在观察者销毁之前,先移除观察者。

KVO其实也可以1对多,就是多个观察者观察同一个对象同一个属性的变化。KVO和通知给人的感觉一个主动通知(通知会由通知中心主动post),一个是被动通知(KVO,观察者一直盯着属性变没变,一旦变化,自己就做出响应。被观察的对象不是主动告知你我变了)。

23.定义一个返回值为字符串类型,参数是int类型的Block。并且调用该Block。

答:Block定义如下所示:

NSString * (^block)(int a) = ^ NSString * (int a){

return [NSString  stringWithFormat:“%d”,a];

};

Block调用:

NSString *str = block(10);

24.请谈谈你对block和delegate模式认识?

答:无论是block还是delegate模式本质上都是回调,使用block,其优点是回调的block代码块直接就放在了block赋值的地方,使代码更为紧凑,缺点是block内使用到当前类的实例变量的时候,需要注意循环引用的问题,即需要使用__block(MRC下)或者__weak(ARC下)定义一个弱引用的self出来,block里面使用弱引用的self去操作属性或调用方法。delegate模式不用像block一样做特殊处理,但是如果多个对象设置的代理是同一个对象,就需要在delegate方法中判断当前执行代理的是哪个对象。

1、block的作用?

1.__block对象在block中是可以被修改、重新赋值的;

2.__block对象在block中不会被block强引用一次,从而不会出现循环引用的问题。

2、block里面能不能修改静态变量(能,__block可以)为什么要用__block

你可以指定引入一个变量为可更改的,即读-写的,通过应用__block存储类型修 饰符。局部变量的__block的存储和register、auto、static等存储类型相似,但它们之 间不兼容。

__block变量保存在变量共享的作用域范围内,所有的blocks和block副本都声明 或创建在和变量的作用域相同范围内。所以,如果任何blocks副本声明在栈内并未超 出栈的结束时,该存储会让栈帧免于被破坏(比如封装为以后执行)。同一作用域范 围内给定的多个block可以同时使用一个共享变量

作为一种优化,block存储在栈上面,就像blocks本身一样。如果使用Block_copy拷贝了block的一个副本(或者在Objective-C里面给block发送了一条copy消息),变量会被拷贝到堆上面。所以一个__block变量的地址可以随时间推移而被更改。

使用__block的变量有两个限制:它们不能是可变长的数组,并且它们不能是包 含有C99可变长度的数组变量的数据结构。

3、声明一个block

声明block

int (^myblock) (int)

说明:第一个int是block的返回值myblock是block变量     第二个int是参数

//举例

在.h中

typedef void(^MyBlock)(int value);

@property (nonatomic,weak) MyBlock block;

-(void)setMyBlock:(void(^)(int value)) block;

在.m中

-(void)setMyBlock:(void(^)(int value)) block {

if (block) {

self.block=block;

}

}

11、ios使用block应当注意什么?

(1)block在实现时就会对它引用到的它所在方法中定义的栈变量进行一次只读拷贝,然后在block块内使用该只读拷贝。

(2)非内联(inline)block不能直接访问self,只能通过将self当作参数传递到block中才能使用,并且此时的self只能通过setter或getter方法访问其属性,不能使用句点式方法。但内联block不受此限制。

(3)使用weak–strong dance技术来避免循环引用

(4)block内存管理分析

block其实也是一个NSObject对象,并且在大多数情况下,block是分配在栈上面的,只有当block被定义为全局变量或block块中没有引用任何automatic变量时,block才分配在全局数据段上。__block变量也是分配在栈上面的。在ARC下,编译器会自动检测为我们处理了block的大部分内存管理,但当将block当作方法参数时候,编译器不会自动检测,需要我们手动拷贝该block对象。

在ARC下,对block变量进行copy始终是安全的,无论它是在栈上,还是全局数据段,还是已经拷贝到堆上。对栈上的block进行copy是将它拷贝到堆上;对全局数据段中的block进行copy不会有任何作用;对堆上的block进行copy只是增加它的引用记数。

如果栈上的block中引用了__block类型的变量,在将该block拷贝到堆上时也会将__block变量拷贝到堆上如果该__block变量在堆上还没有对应的拷贝的话,否则就增加堆上对应的拷贝的引用记数。

http://my.oschina.net/u/1432769/blog/390401

2.kvo除了能观察属性外,能不能观察对象

不能观察对象

KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了

KVO是一个对象能够观察另外一个对象的属性的值,并且能够发现值的变化。这是一个对象与另外一个对象保持同步的一种方法,即当另外一种对象的状态发生改变时,观察对象马上作出反应。它只能用来对属性作出反应,而不会用来对方法或者动作作出反应。

实现原理:当为某一个对象属性注册监听的时候,该对象的isa指针就会指向一个中间类,而不是本来对象真实的类。所以说,对象的isa指针可以改变,我们的程序最好不要依赖isa指针。

简而言之就是:

1、当一个object有观察者时,动态创建这个object的类的子类

2、对于每个被观察的property,重写其set方法

3、在重写的set方法中调用- willChangeValueForKey:和- didChangeValueForKey:通知观察者

4、当一个property没有观察者时,删除重写的方法

5、当没有observer观察任何一个property时,删除动态创建的子类

10、简述在app中所应用到设计模式

(一)代理模式

应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现。

优势:解耦合

敏捷原则:开放-封闭原则

实例:tableview的 数据源delegate,通过和protocol的配合,完成委托诉求。

列表row个数delegate

自定义的delegate

(二)观察者模式

应用场景:一般为model层对,controller和view进行的通知方式,不关心谁去接收,只负责发布信息。

优势:解耦合

敏捷原则:接口隔离原则,开放-封闭原则

实例:Notification通知中心,注册通知中心,任何位置可以发送消息,注册观察者的对象可以接收。

kvo,键值对改变通知的观察者,平时基本没用过。

(三)MVC模式

应用场景:是一中非常古老的设计模式,通过数据模型,控制器逻辑,视图展示将应用程序进行逻辑划分。

优势:使系统,层次清晰,职责分明,易于维护

敏捷原则:对扩展开放-对修改封闭

实例:model-即数据模型,view-视图展示,controller进行UI展现和数据交互的逻辑控制。

(四)单例模式

应用场景:确保程序运行期某个类,只有一份实例,用于进行资源共享控制。

优势:使用简单,延时求值,易于跨模块

敏捷原则:单一职责原则

实例:[UIApplication sharedApplication]。

注意事项:确保使用者只能通过getInstance方法才能获得,单例类的唯一实例。

java,C++中使其没有公有构造函数,私有化并覆盖其构造函数。

object c中,重写allocWithZone方法,保证即使用户用alloc方法直接创建单例类的实例,

返回的也只是此单例类的唯一静态变量。

(五)策略模式

应用场景:定义算法族,封装起来,使他们之间可以相互替换。

优势:使算法的变化独立于使用算法的用户

敏捷原则:接口隔离原则;多用组合,少用继承;针对接口编程,而非实现。

实例:排序算法,NSArray的sortedArrayUsingSelector;经典的鸭子会叫,会飞案例。

注意事项:1,剥离类中易于变化的行为,通过组合的方式嵌入抽象基类

2,变化的行为抽象基类为,所有可变变化的父类

3,用户类的最终实例,通过注入行为实例的方式,设定易变行为

防止了继承行为方式,导致无关行为污染子类。完成了策略封装和可替换性。

(六)工厂模式

应用场景:工厂方式创建类的实例,多与proxy模式配合,创建可替换代理类。

优势:易于替换,面向抽象编程,application只与抽象工厂和易变类的共性抽象类发生调用关系。

敏捷原则:DIP依赖倒置原则

实例:项目部署环境中依赖多个不同类型的数据库时,需要使用工厂配合proxy完成易用性替换

注意事项:项目初期,软件结构和需求都没有稳定下来时,不建议使用此模式,因为其劣势也很明显,

增 加了代码的复杂度,增加了调用层次,增加了内存负担。所以要注意防止模式的滥用。

8.使用block和使用delegate完成委托模式有什么优点?

委托模式在iOS中大量应用,其在设计模式中是适配器模式中的对象适配器,Objective-C中使用id类型指向一切对象,使委托模式更为简洁。

block

优点:

1.语法简洁,实现回调不需要显示的调用方法,代码更为紧凑。

2.增强代码的可读性和可维护性。

3.配合GCD优秀的解决多线程问题。

缺点:

1.Block中得代码将自动进行一次retain操作,容易造成内存泄露。

2.Block内默认引用为强引用,容易造成循环引用。

代理:

优点:

1.减少代码的耦合性,使事件监听和事件处理相分离。

2.清晰的语法定义,减少维护成本,较强的代码可读性。

3.不需要创建第三方来监听事件和传输数据。

4.一个控制器可以实现多个代理,满足自定义开发需求,可选必选有较大的灵活性。

缺点:

1.实现委托的代码过程比较繁琐。

2.当实现跨层传值监听的时候将加大代码的耦合性,并且程序的层次结构将变的混乱。

3.当对多个对象同时传值响应的时候,委托的易用性将

10.何时使用代理,何时使用通知;

代理:一般控件用的比较多,其实也可以用block实现,如果实现的接口比较多的话,建议用代理,如UITableview。

如果一个类能够获取到通知的对象,这种情况下,我们用代理的效率会更高,而且能够更好的实现对要代理的对象的管理。

通知:这东西是全局的,而且是同步的,如果你要全局发送消息,并且做的事情时间不长,不会阻塞线程的话,建议使用。

如果一个通知的发送者有多个接受者,而且接受的位置完全不确定,那么这种情况下用通知是比较好的方式

37. block在ARC中和MRC中的用法有什么区别,需要注意什么

①.对于没有引用外部变量的Block,无论在ARC还是非ARC下,类型都是__NSGlobalBlock__,这种类型的block可以理解成一种全局的block,不需要考虑作用域问题。同时,对他进行Copy或者Retain操作也是无效的

②.应注意避免循环引用

36.类工厂方法是什么

类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中, 返回被创建的对象,并

进行自动释放处理。这些方法的形式是+ (type)className...(其中className不包括任何前缀)。

工厂方法可能不仅仅为了方便使用。它们不但可以将分配和初始化合在一起,还可以 为初始化过程提供对

象的分配信息。

类工厂方法的另一个目的是使类(比如NSWorkspace)提供单件实例。虽 然init...方法可以确认一

个类在每次程序运行过程只存在一个实例,但它需要首先分配一个“生的”实例,然后还必须释放该实例。

工厂 方法则可以避免为可能没有用的对象盲目分配内存。

43.代理和协议什么区别

代理是一种概念,协议是一种技术,代理是用协议来实现的,代理 是2个对象之间通讯的一种方式。 代理主要做反向传值的。实现系统的一些回调方法,比如scrollview滑动事件,选择照片,asi网络下载完成等.iOS开发和Objective-c区别

50.在block内如何修改block外部变量?

默认情况下,在block中访问的外部变量是复制过去的,即:写操作不对原变量生效。但是你可以加上__block来让其写操作生效,示例代码如下:

__block int a = 0;

void  (^foo)(void) = ^{

a = 1;

}

f00();

//这里,a的值被修改为1

53.使用block时什么情况会发生引用循环,如何解决?

一个对象中强引用了block,在block中又使用了该对象,就会发射循环引用。 解决方法是将该对象使用__weak或者__block修饰符修饰之后再在block中使用。

id weak weakSelf = self;或者weak __typeof(&*self)weakSelf = self该方法可以设置宏

id __block weakSelf = self;

block中的weak self,是任何时候都需要加的么?

(2)block

block在copy时都会对block内部用到的对象进行强引用(ARC)或者retainCount增1(非ARC)。在ARC与非ARC环境下对block使用不当都会引起循环引用问题,一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身,简单说就是self.someBlock = ^(Type var){[self dosomething];或者self.otherVar = XXX;或者_otherVar = ...};block的这种循环引用会被编译器捕捉到并及时提醒

95.哪些类不适合使用单例模式?即使他们在周期中只会出现一次。

工具类,不需要存储数据的.

简明概要的说明了KVO和NSNotification的区别:

和delegate一样,KVO和NSNotification的作用也是类与类之间的通信,与delegate不同的是1)这两个都是负责发出通知,剩下的事情就不管了,所以没有返回值;2)delegate只是一对一,而这两个可以一对多。这两者也有各自的特点。

1)KVO的使用:

被观察者发出addObserver:forKeyPath:options:context:方法来添加观察者。

然后只要被观察者的keyPath值变化(注意:单纯改变其值不会调用此方法,只有通过getters和setters来改变值才会触发KVO),就会在观察者里调用方法observeValueForKeyPath:ofObject:change:context:

因此观察者需要实现方法observeValueForKeyPath:ofObject:change:context:来对KVO发出的通知做出响应。

这 些代码都只需在观察者里进行实现,被观察者不用添加任何代码,所以谁要监听谁注册,然后对响应进行处理即可,使得观察者与被观察者完全解耦,运用很灵活很 简便;但是KVO只能检测类中的属性,并且属性名都是通过NSString来查找,编译器不会帮你检错和补全,纯手敲所以比较容易出错。

2)NSNotification的使用

这里的通知不是由被观察者发出,而是由NSNotificationCenter来统一发出,而不同通知通过唯一的通知标识名notificationName来区分,标识名由发送通知的类来起。

首先被观察者自己在必要的方法A里,通过方法postNotificationName:object:来发出通知notificationName这样发送通知者这边的工作就完成了,每次A被调用,就会发送一次通知notificationName。

然后谁要监听A的变化,就通过[NSNotificationCenter defaultCenter]的方法addObserver:selector:name:object:为观察者注册监听name为notificationName的通知然后每次发出name为notificationName的通知时,注册监听后的观察者就会调用其自己定义的方法notificationSelector来进行响应。

NSNotification的特点呢,就是需要被观察者先主动发出通知,然后观察者注册监听后再来进行响应,比KVO多了发送通知的一步,但是其优点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,使用也更灵活。

MVC模式及好处?

MVC是三个单词的缩写,分别为:

模型(Model),视图(View)和控制Controller)。

MVC模式的目的就是实现Web系统的职能分工。

Model层实现系统中的业务逻辑,通常可以用JavaBean或EJB来实现。

View层用于与用户的交互,通常用JSP来实现。

Controller层是Model与View之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。

MVC模式的好处

1.各施其职,互不干涉

在MVC模式中,三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相应的层中的代码而不会影响到其它层中的代码。

2.有利于开发中的分工

在MVC模式中,由于按层把系统开,那么就能更好的实现开发中的分工。网页设计人员可以进行开发视图层中的JSP,对业务熟悉的开发人员可开发业务层,而其它开发人员可开发控层。

3.有利于组件的重用

分层后更有利于组件的重用。如控制层可独立成一个能用的组件,视图层也可做成通用的操作界面。

MVC(Model-View-Controller)应用程序结构被用来分析分布式应用程序的特征。这种抽象结构能有助于将应用程序分割成若干逻辑部件,使程序设计变得更加容易。

MVC结构提供了一种按功能对各种对象进行分割的方法(这些对象是用来维护和表现数的),其目的是为了将各对象间的耦合程度减至最小。MVC结构本来是为了将传统的输入(input)、处理(processing)、输出(output)任务运用到图形化用户交互模型中而设计的。但是,将这些概念运用于基于Web的企业级多层应用领域也是很适合的。

在MVC结构中,模型(Model)代表应用程序的数据(data)和用于控制访问和修改这些数据的业务规则(business rule)。通常模型被用来作为对现实世界中一个处理过程的软件近似,当定义一个模型时,可以采用一般的简单的建模技术。

当模型发生改变时,它会通知视(View),并且为视提供查询模型相关状态的能力。同时,它也为控制器(Controller)提供访问封装在模型内部的应用程序功能的能力。

一个视(View)用来组织模型的内容。它从模型那里获得数据并指定这些数据如何表现。当模型变化时,视负责维持数据表现的一致性。视同时将用户要求告知控制器(Controller)。

控制器(Controller)定义了应用程序的行为;它负责对来自视的用户要求进行解释,并把这些要求映射成相应的行为,这些行为由模型负责实现。在独立运行的GUI客户端,用户要求可能是一些鼠标单击或是菜单选择操作。在一个Web应用程序中,它们的表现形式可能是一些来自客户端的GET或POST的HTTP请求。模型所实现的行为包括处理业务和修改模型的状态。根据用户要求和模型行为的结果,控制器选择一个视作为对用户请求的应答。通常一组相关功能集对应一个控制器。

1)各施其职,互不干涉

在MVC模式中,三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相应的层中的代码而不会影响到其它层中的代码。假如业务发生了变化,如在取文章时可能webmaster把一些文章作了无效标志,不能直接把所有文章取出来,只能取出有效的文章,这时业务就发生了改变。再设想一下,如果这个业务逻辑在100个页面中都要用到,那么MVC模式就体现了它的灵活性。我们可以不更改任何JSP,只要更改model层中的相应类中的SQL语句即可。

2)有利于开发中的分工

在MVC模式中,由于按层把系统开,那么就能更好的实现开发中的分工。网页设计人员可以进行开发视图层中的JSP,对业务熟悉的开发人员可开发业务层,而其它开发人员可开发控制层。

3)有利于组件的重用

分层后更有利于组件的重用。如控制层可独立成一个能用的组件,视力层也可做成通用的操作界面

10、声明block属性的时候为什么⽤用copy?

避免block被系统释放,因为⼀一开始block是在栈中的,只有copy后的block才会

在堆中。

Block属性的声明,⾸首先需要⽤用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的⽣生命周期是和栈绑定的,避免编译器将其释放;

(拓展)block与线程安全另⼀一个需要注意的问题是关于线程安全,在声明Block属性时需要确认“在调⽤用

Block时另⼀一个线程有没有可能去修改Block?”这个问题,如果确定不会有这种情况发⽣生的话,那么Block属性声明可以⽤用nonatomic。如果不肯定的话(通常情况是这样的),那么你⾸首先需要声明Block属性为atomic,也就是先保证变量的原⼦子性(Objective-C并没有强制规定指针读写的原⼦子性,C#有)。

⽐比如这样⼀一个Block类型: typedef void (^MyBlockType)(int);

属性声明:

@property (copy) MyBlockType myBlock;

这⾥里ARC和⾮非ARC声明都是⼀一样的,当然注意在⾮非ARC下要release Block。

但是,有了atomic来保证基本的原⼦子性还是没有达到线程安全的,接着在调⽤用时需要把Block先赋值给本地变量,以防⽌止Block突然改变。因为如果不这样的话,即便是先判断了Block属性不为空,在调⽤用之前,⼀一旦另⼀一个线程把Block属性设空了,程序就会crash,如下代码:

if (self.myBlock)

{

//此时,⾛走到这⾥里,self.myBlock可能被另⼀一个线程改为空,造成crash //注意:atomic只会确保myBlock的原⼦子性,这种操作本⾝身还是⾮非线程安全的self.myBlock(123);

}

所以正确的代码是(ARC): MyBlockType block = self.myBlock; //block现在是本地不可变的

if (block)

{ block(123); }

在⾮非ARC下则需要⼿手动retain⼀一下,否则如果属性被置空,本地变量就成了野指针了,如下代码:

//⾮非ARC

MyBlockType block = [self.myBlock retain];

if (block)

{ block(123); }

[block release];

4.(口述)NSNotification和KVO的区别和用法是什么?什么时候应该使用通知,什么时候应该使用KVO,它们的实现上有什么区别吗?如果用protocol和delegate(或者delegate的Array)来实现类似的功能可能吗?如果可能,会有什么潜在的问题?如果不能,为什么?

2、非自动内存管理情况下怎么做单例模式

非ARC内存管理模式下对象必须手动释放,为了防止那个唯一的单例对象被释放掉,则只需要重写下面的几个方法即可

+(instancetype) allocWithZone:(struct _NSZone *)zone

-(instancetype) copyWithZone:(NSZone*)zone

-(id) retain

-(oneway void) release

-(instancetype) autorelease

-(unsigned) retainCount

http://www.cnblogs.com/heyonggang/p/3553840.html

4、What is Singleton pattern? Please try to implement one

单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

在iOS中,单例有两种实现方式。根据线程安全的实现来区分,一种是使用@synchronized,另一种是使用GCD的dispatch_once函数。

要实现单例,首先需要一个static的指向类本身的对象,其次需要一个初始化类函数。下面是两种实现的代码。

1、@synchronized

static InstanceClass *instance;

+ (InstanceClass *)defaultInstance{

@synchronized (self){

if (instance == nil) {

instance = [[InstanceClass alloc] init];

}

}

return instance;

}

2、GCD

static InstanceClass *instance;

+ (InstanceClass *)defaultInstance{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

instance = [[InstanceClass alloc] init];

});

return instance;

}

2.MRC下的单例需要注意什么

因为 单例对象 是用static标记过的,因此存放在 静态区.所以在MRC中 不需要 由程序员 去管理,因此要去覆盖一些 内存 管理的方法.

实现部分与ARC一致,只需要 覆盖 一些MRC中 内存 管理 的方法:

* -  (id)retain .单例中不需要增加引用计数器. return self.

* - (id)autorelease .只有堆中的对象才需要.单例中不需要.return self.

* - (NSUInteger)retainCount . (可写可不写,防止引起误解).单例中不需要修改引用计数,返回最大的无符号整数即可.return UINT_MAX;

*- (oneway void)release .不需要release.直接覆盖,声明也不做.

单例模式(ARC)与(MRC)

http://www.mamicode.com/info-detail-364051.html

i������

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

推荐阅读更多精彩内容

  • 设计模式分析比较? 1、单例设计模式:在项目中,单例是必不可少的。比如UIApplication、NSUserDe...
    Carden阅读 333评论 0 1
  • 1.什么是观察者模式?2.为什么要用观察者模式?它的优缺点是什么?![Uploading 屏幕快照 2016-12...
    羊妞麻麻阅读 689评论 0 0
  • 你可以下载the project source from the end of part 1与我们共同来探索 这是...
    木易林1阅读 391评论 0 0
  • MVC: Model: 负责存储,定义,操作数据;View: 用来展示给用户数据,和用户进行交互操作的;Contr...
    西风颂阅读 721评论 4 20
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,040评论 29 470