Swift网络请求md5等加密库使用

import Alamofire swift版本的afnetworking

https://github.com/Alamofire/Alamofire

import CryptoSwift swift版本的各种加密包括md5 SHA AES….

https://github.com/krzyzanowskim/CryptoSwift

这里直接说使用:
get请求

md5:

var md5ArrStr :String;
md5ArrStr = md5ArrStr.md5()

传的参数
let parameters:Dictionary = [“stampToken”:stampToken,”checkToken”:md5ArrStr];

Alamofire.request(.GET, “https://safdsafd.com/api/v2/project/fsda”, parameters: parameters)
.responseJSON { response in

        print("result==\(response.result)")   // 返回结果,是否成功
        if let jsonValue = response.result.value {

            print("code: \(jsonValue["respDesc"])")
        }
}

后台返回可以通过 jsonValue来获取相应key的值

详细的使用和见解请持续关注,支持,有什么疑问 可以评论


如何学习iOS

这里说说我自己对学习iOS的一些建议吧

第一要多读多思考

这点是必须的,比如一些像我们平时经常使用的gcd core data afnetworking sdwebimage 等等这些我们使用的系统机制或第三方的一些好的库,我们都应该不仅仅是停留在使用的方面,更应该知道他里面的原理,看一遍不懂就多看几次,还有像多看别人的经验,比如tableview的一些优化,比如性能的一些分析,多多思考,思考的时候最好可以记录下来思考的一些结果,这样有助于在实践的时候方便去验证,还有就是苹果提供的一些视频WWDC和文档都是非常好的阅读和思考以及同行交流直播等。

第二要大量实践

思考了以后就是动手了,来实践验证自己所想的是不是对的,而且动手实践的好处就是中间会遇到各种各样的问题,问题越是多,说明你提升的空间越大,如果你觉得难,那么不要放弃,你正是在走上坡路.这里为什么说大量实践呢,我们大家都知道熟能生巧这个词,我们的大脑忘记事情会很快,如果你只是做一次,并且只是按照别人的思路来copy很容易忘记.所以只有大量的去实践才能真正领悟.

第三要疯狂的总结

总结真的是很关键,如果你一直在开发东西而不去做总结的话,其实你所做过的东西,在以后的时候,很容易忘记,很容易不知道这么久了,进步了哪些?其中遇到了什么问题?自己是怎么解决的?等等..这些好的方法和问题等都是宝贵的财富,因为很多事情都是有关联的,这些问题不会只发生一次,它可能以后会变相出现,也可以下次一模一样,所以总结可以一劳永逸.

第四要画脑图

在iOS这个领域里,可能牵扯到太多太多其他的东西,图形学,视频,音频,文字,硬件,通信,动画等等领域,但是这些他们之前的发展一路过来都是历史,无法去改变,这也就让我们能够学到一成不变的经典,一路过来可以画脑图可以更清楚地了解,这些都是你通往专家的道路.但是毕竟每个人的时间有限,需求也不同,兴趣也不同,所以不管是上面哪一个都是要花大量时间去学习去总结去实践和改良的.所以只能说尽量多学点多掌握些吧,或者选择一个专心研究下去,我还是比较提倡一件事情做完再去做另一件事情的.尤其是专业方面的东西.只是先后顺序而已.

总结,最后要说的是多复习,这点就不多说了,就是对以上的进行复习,多磨合,不然上面的就白做了.温故而知新.上面忘记提书了,看书还是很关键的,如果能把薄书读厚,又能把厚书读薄,就真的非常不错了!愿大家早日变成行业精英,都能够更有兴趣更好的成长,升职 加薪 出任ceo 赢取白富美.


iOS非闲聊研讨群:328218600

Swift tabbarController

自定义实现 swift版本的tabbarController,很常用,容易扩展和维护 ,更多好的开源请关注我的github地址

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?


var navigationVC : NSMutableArray!

func controllerWithBarTitle (title : String , viewControllerClass :UIViewController , tag: NSInteger , tabbarIconImageName :String )
{
    let viewController : UIViewController =   viewControllerClass;

    let navigationVC = UINavigationController(rootViewController: viewController);

    let tabbarAPengDaiImage = UIImage(named: tabbarIconImageName);

    navigationVC.tabBarItem = UITabBarItem(title:title,image:tabbarAPengDaiImage,tag:tag);
    if((self.navigationVC) == nil)
    {
        self.navigationVC = NSMutableArray()
    }
    self.navigationVC! .addObject(navigationVC);

}

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    //  UITabBarController
    let tabBarController = UITabBarController();

    self .controllerWithBarTitle("AAA", viewControllerClass: AAAViewController(), tag: 1, tabbarIconImageName: "TabBar_HomeNormal.png");

    self .controllerWithBarTitle("BB财", viewControllerClass: InvestmentViewController(), tag: 2, tabbarIconImageName: "TabBar_InvestmentNormal.png");

    self .controllerWithBarTitle("CC户", viewControllerClass: AccountViewController(), tag: 3, tabbarIconImageName: "TabBar_AccountNormal.png");

    self .controllerWithBarTitle("邀请好友", viewControllerClass: InviteViewController(), tag: 4, tabbarIconImageName: "TabBar_InviteNormal.png");

    print(self.navigationVC);


    tabBarController.viewControllers = self.navigationVC as?[UIViewController];
    /*
    as操作符用来把某个实例转型为另外的类型,由于实例转型可能失败,因此Swift为as操作符提供了两种形式:选项形式as?和强制形式as

    选项形式(as?)的操作执行转换并返回期望类型的一个选项值,如果转换成功则返回的选项包含有效值,否则选项值为 nil 强制形式(as )的操作执行一个实例到目的类型的强制转换,因此使用该形式可能触发一个运行时错误。
    */

    self.window!.rootViewController = tabBarController;
    /*
    self.window!.和self.window?.区别
    个人理解
    ! 是强制取值( forced- value) 表达式,
    ? 是(optional chaining expression) 可选链表达式。
    ?是你不确定opt里面有没有东西,!是你确定里面有东西,当然没有东西的也可以!,但是会分分钟崩溃给你看 ! 号编译器可以分析你的代码

    */


    return true
}

UIWindow和UIView和CALayer的联系和区别

UIView,UIWindow和CALayer都有共同的基类NSObject,UIView继承于UIResponder,所以UIView可以响应用户事件,CALayer是继承于NSObject所以不可以响应用户事件.UIView侧重于对内容的管理,CALayer侧重于对内容的绘制. UIWindow是特殊的UIView,通常一个app只有一个UIWindow,我们可以创建一个视图控制器,然后将这个视图控制器添加到UIWindow上面,这时这个视图控制器就是app的First Responder.

UIView是视图的基类,UIViewController是视图控制器的基类,UIResponder是表示一个可以在屏幕上响应触摸事件的对象;
UIwindow是UIView的子类,UIWindow的主要作用:一是提供一个区域来显示UIView,二是将事件(event)的分发给UIView,一个应用基本上只有一个UIWindow.
万物归根,UIView和CALayer都是的老祖都是NSObjet。可见UIResponder是用来响应事件的,也就是UIView可以响应用户事件。
  
CALayer和UIView的区别:
1.1 UIView的继承结构为: UIResponder : NSObject。
CALayer的继承结构为: NSObject。可见UIResponder是用来响应事件的,也就是UIView可以响应用户事件,CALayer直接从NSObject继承,因为缺少了UIResponder类,不能响应任何用户事件。
1.2所属框架,UIView是在/System/Library/Frameworks/UIKit.framework中定义的,UIKit主要是用来构建用户界面,并且是可以响应事件的。CALayer是在/System/Library/Frameworks/QuartzCore.framework定义的。而且CALayer作为一个低级的,可以承载绘制内容的底层对象出现在该框架中。
1.3 UIView相比CALayer最大区别是UIView可以响应用户事件,而CALayer不可以。UIView侧重于对显示内容的管理,CALayer侧重于对内容的绘制。UIView是基于CALayer的高层封装。
1.4相似支持1:相似的树形结构2:显示内容绘制方式3:布局约束
总结一下就是:UIView是用来显示内容的,可以处理用户事件.CALayer是用来绘制内容的,对内容进行动画处理依赖与UIView来进行显示,不能处理用户事件

http://tieba.baidu.com/p/4239135997
http://www.thinksaas.cn/group/topic/396637/

iOS里的各种通知及机制

通知、本地通知和推送通知区别以及APNS 的机制

对于很多初学者往往会把iOS中的本地通知、推送通知和iOS通知中心的概念弄混。其实二者之间并没有任何关系,事实上它们都不属于一个框架,前者属于UIKit框架,后者属于Foundation框架。

通知中心实际上是iOS程序内部之间的一种消息广播机制,主要为了解决应用程序内部不同对象之间解耦而设计。它是基于观察者模式设计的,不能跨应用程序进程通信,当通知中心接收到消息之后会根据内部的消息转发表,将消息发送给订阅者。

iOS中通知机制又叫消息机制,其包括两类:一类是本地通知;另一类是推送通知,也叫远程通知。
两种通知在iOS中的表现一致,可以通过横幅或者弹出提醒两种形式告诉用户,并且点击通知可以会打开应用程序,但是实现原理却完全不同。

本地通知是由本地应用触发的,它是基于时间行为的一种通知形式,例如闹钟定时、待办事项提醒
又或者一个应用在一段时候后不使用通常会提示用户使用此应用等都是本地通知。

在iOS中如果点击一个弹出通知(或者锁屏界面滑动查看通知),默认会自动打开当前应用。

由于通知由系统调度那么此时进入应用有两种情况:如果应用程序已经完全退出那么此时会调用- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions方法;

如果此时应用程序还在运行(无论是在前台还是在后台)则会调用-(void)application:(UIApplication )application didReceiveLocalNotification:(UILocalNotification )notification方法接收消息参数。当然如果是后者自然不必多说,因为参数中已经可以拿到notification对象,只要读取userInfo属性即可。如果是前者的话则可以访问launchOptions中键为UIApplicationLaunchOptionsLocalNotificationKey的对象,这个对象就是发送的通知,由此对象再去访问userInfo。为了演示这个过程在下面的程序中将userInfo的内容写入文件以便模拟关闭程序后再通过点击通知打开应用获取userInfo的过程。

和本地通知不同,推送通知是由应用服务提供商发起的,

通过苹果的APNs(Apple Push Notification Server)发送到应用客户端

http://www.cnblogs.com/kenshincui/p/4168532.html

待补充……

两个数组取不同值

1.现有两个无序数组a和b,b中的元素在a中都存在,请设计一个方案,找出在a中,但不在b中的所有元素.请考虑降低时间复杂度.

方法1: //首先呢,前看看苹果是否提供这类的比较方法
很幸运,苹果提供了 NSPredicate,它所属Cocoa框架.利用它可以做类似数据库那样的查询 筛选等..

链接:http://zhidao.baidu.com/link?url=96djsD_wancK72DLlCQLPuQHzkdAEtsI0J-C8VSh4KNplCn4mOURHoz48Qu8fKqlAhfIkcCge94WAsdmZz7IS-Y-8M8jTBEPAAJ1vut0Jku

注:NSPredicate所属Cocoa框架,在密码、用户名等正则判断中经常用到.
类似于SQL语句
NOT 不是
SELF 代表字符串本身
IN 范围运算符
那么NOT (SELF IN %@) 意思就是:不是这里所指定的字符串的值
实验代码:

NSArray *aArray = [[NSArray alloc] initWithObjects:@”0”,@”8”,@”9”,@”2”,@”1”,@”5”,nil];

NSArray *bArray =  [[NSArray alloc] initWithObjects:@"2",@"0",@"1",@"5",nil];

NSPredicate * filterPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",bArray];
//过滤数组
NSArray * reslutFilteredArray = [aArray filteredArrayUsingPredicate:filterPredicate];

NSLog(@"Reslut Filtered Array = %@“,reslutFilteredArray);

思考 苹果这样做 时间和复杂程度有哪些好处?

方法2:通过遍历(1)
NSMutableArray reslutArr = [[NSMutableArray alloc] initWithArray:aArray];
for(int i = 0 ; i < aArray.count; i++)
{
NSString
aStr = aArray[i];
NSLog(@”aStr:%@”,aStr);
for (int j = 0; j< bArray.count; j++) {
NSString *bStr = bArray[j];
if([aStr isEqualToString:bStr])
{
NSLog(@”%@”,bStr);
[reslutArr removeObject:aStr];
break;
}
}
}
NSLog(@“reslutArr:%@“,reslutArr);

//遍历(2) 对1的优化. 从后往前遍历数组,然后匹配删除.使用containsObject方法的场景很常见,例如:判断某一个元素(对象)是否存在数组中.
int i = (int)[aArray count]-1;
for(;i >= 0;i –){
//containsObject 判断元素是否存在于数组中(根据两者的内存地址判断,相同:YES 不同:NO)
if([bArray containsObject:[aArray objectAtIndex:i]]) {
[aArray removeObjectAtIndex:i];
}
}
NSLog(@”Data Array = %@“,aArray);

//这里的aArray修改成了可变数组 方便removeObject不用定义第三个数组

/ 遍历(3) 通过字典key 来进行对另一个数组的remove
时间复杂度为n,一重For循环B数组 考虑b数组比a数组大,换成循环a数组 先将a数组转换成字典,所有元素作为Key 然后遍历B数组,B.元素作为Key到a字典去取值 这样时间复杂度为2n 我说的是纯算法,与具体编程语言无关
/
NSMutableDictionary dic = [[NSMutableDictionary alloc] init];
for (int i = 0 ;i< aArray.count ; i ++)
{
NSString
aKey = aArray[i];
[dic setValue:@”1” forKey:aKey];
}
NSLog(@”dic:%@”,dic);
for (int j = 0; j < bArray.count; j++) {

    NSString *bKey =  bArray[j];
   [dic removeObjectForKey:bKey];
    NSLog(@"dic.allKeys:%@",dic.allKeys);
}

//思考比较这几种的 时间复杂度,比较下哪个最优?

测试两段代码运行速度
http://www.cocoachina.com/ios/20100721/1901.html
我打印了下时间 ,通过遍历和方法1 用了 :
谓词和遍历 2016-03-06 11:45:23.717 TestAB[1000:69199] >>>>>>>>>>cost time = 0.000007
通过字典这种方法用了 2016-03-06 11:46:47.528 TestAB[1036:71234] >>>>>>>>>>cost time = 0.000011

也就是说 最好还是用系统自带的谓词或者用自己写的遍历会计算机处理会快一些.当然字典这种也是简便清晰快捷的方法.

具体代码请看我的github地址:https://github.com/jiecoding/ABArrayAlgorithm

关于面试

刚跳槽去了一个新公司,准备招个高级IOS工程师。于是这周就开始我的面试经历。面试别人,真是让我见识到IT行业的水有多深:
第一个:简历上写三年IOS工作经验,简历上一大堆项目,要18k。说上家公司是唯品会,然后说以前做的项目多牛逼啥的。面试结果是一问三不知。
第二个:简历上写五年iOS工作经验,西北大学毕业,然后说上家公司倒闭等等之类的。要25k。吹自己多牛逼,一问三不知,一个劲的吹自己创业了没有学习总结,等等如云。
第三个:简历上写的两年半iOS,然后以来就给我一个淘宝scrollview的拉动效果,问他怎么实现的,就一句很复杂,一句话说不清楚。撤了一半天以后,我就问他一个关于scrollview的几个属性,让我震惊的一幕发生了,他说:面试无法继续,就走了。。。我操他妈。骗人还有理了,一副吊儿郎当的样子老子见到就烦。
第四个:最扯也是最让我反思的一个,34了,简历上写浙大毕业,然后好多工作经验啊,反正也是干iOS都几年了,问他技术问题就一句话:这个我不知道,基本的需求我都会,然后离线保存里几篇博客拿来忽悠我。薪水震惊的要到了30k,要是他值30k,我都不知道要向公司要多少了。
第五个:这个是最靠谱的一个也是差点蒙混过关的一个,第一个是他要的薪水11-13k。第二个相对于前面几个一问三不知,他能回答一点,其实我没发现破绽,也准备向公司说要他给11k。结果我的小伙伴点开他说它说在公司的app。。全是近一个月左右上线的,而且全是1.0。总共有几十个。当时让我心里拔凉拔凉的,亏老子对他这么客气。而且我怀疑他说他不舒服是装的,一问到不知道的问题就摸着头,说刚来上海水土不服。有可能是背了一些面试题。

我只想对他们说:你们他妈的就是人渣,以为会做点简单的我功能就牛逼了,而且最可恶的是他们没有一点愧疚感,以为骗人还有理了。太浮躁了。

他们的共同特点是:
1 都是几年工作iOS经验,好像一般都是3年左右,最高的达到了吃惊的5年。原来培训出来吹两年工作经验的算有良心得了。
2 上家公司要么倒闭,要么是知名企业但是做的事企业内部用的不上线等、要么就是做的知名企业的项目的老版本,然后现在的版本不是他做的。要么上家公司是外包等等如云。
3没有技术总结、基本没有博客,没有用github。问看过什么进阶的书一般都说没有。
4一来一般都会吹自己做的某个功能特别牛逼。一问详细点就不行了,以各种借口搪塞。
5会装,一个屌丝装创业失败、各种想好的故事。
6技术能力与他说的iOS工作年限严重不符合。

以上符合两点的就需要仔细甄别。符合三点的一般就是吹得。忘各位同仁擦亮眼睛,别让这种风气继续下去。

我最震惊的是,他们那里来的勇气这样吹?这样高的薪资要。搞的我每次面试以后干活的心情都没有了。哎。。。。。
这行真的水太深了,以前还真不知道。shit。。。

上面是一个不知名的博友写的总结,感觉还不错。

我自己的看法是上面这几个无非有两点:
1.刚培训出来的。
2.工作了很久都是混日子的。

不管是上面哪个,自己感觉都挺不靠谱的,其实都是耽误自己的时间。我还是坚信一寸技术一寸金

当然说完面试者 说说面试官

其实也不能全怪所有的面试者,有的面试官出的题就很2b 简直是用来装逼的 不是用来考人的

就好比我拆过iphone手机 你没有拆过 我就说你没用过苹果手机 你不就是为了装逼你拆过么

还有问你某个功能在第几个选项这种扯淡的问题,谁能记得那么清楚…

问项目我感觉还是比较靠谱的,毕竟如果真做过的你往深里问就能问出个差不多 , 但是如果蛋疼的为了招一个薪水本来就不是很高的问题,问一大顿操作系统的东西,我觉得脑子里简直有屎。麻烦面试官在面试别人前先想想自己到底要招一个什么样的人,薪水在什么范围的,技术在什么范围的,不要面试的时候连自己都不知道要什么样的人。

对于面试者还是多多提高自身技术,虽然有的时候面试靠碰运气,但是运气几率也是随着综合实力的增加而增加…

iOS Runtime

简单介绍下runtime
http://www.cocoachina.com/ios/20141018/9960.html

http://zhiwei.li/text/2014/08/09/objective-c运行时objc_msgsend_stret/

我们在运行代码的时候 像下面这个方法:

[target doMethodWith:var1]; 运行时会转换为 objc_msgSend(target,@selector(doMethodWith:),var1); C语言函数指针

关于runtime的一些问题:http://blog.csdn.net/a19860903/article/details/45044701

第一、文章里面有一个问题:

下面的代码输出什么?

@implementation Son : Father

  • (id)init

{

self = [super init];

if (self)

{

    NSLog(@"%@", NSStringFromClass([self class]));

    NSLog(@"%@", NSStringFromClass([super class]));

}

return self;

}

@end

答案:都输出 Son (前提是father和son类都没有重写class这个方法,而是调用的nsobject的class方法)

首先对于这个题,如果Son类没有重写class方法,而Father类里重写了NSObject的class这个方法,那么[self class] 会去调用父类Father里的class方法,如果想要上面输出: Son 和 Father这种正确的类名,那么就要重写两个类的class方法:

Son.m
//- (Class)class OBJC_SWIFT_UNAVAILABLE(“use ‘anObject.dynamicType’ instead”)
//{
// return [Son class];
//}

Father.m
//- (Class)class OBJC_SWIFT_UNAVAILABLE(“use ‘anObject.dynamicType’ instead”)
//{
// return [Father class];
//}

首先这道题,如果你想打印父类,那么就不应该这样写:

NSLog(@”%@”, NSStringFromClass([super class]));

而是:

NSLog(@”%@”,NSStringFromClass([self superclass]));

达到我们需要的结果后,我们就要思考,上面那段为什么会都输出Son呢,到底进行了什么?

首先前面说到过类似 [self class] 这种 会在运行时转换成 objc_msgSend 函数,objc_msgSend, 它就是负责发送一个消息给对象的C函数

objc-runtime.h 里面

#include

#include

objc_msgSend 和 objc_msgSendSuper 就是在message.h 类里

这个函数 objc_msgSend(<#id#>, <#SEL, …#>)
有两个参数

id objc_msgSend(id self, SEL op, …)
我们把 self 做为第一个参数传递进去。

id objc_msgSendSuper(struct objc_super *super, SEL op, …)

第一个参数是 objc_super 这样一个结构体,其定义如下:

struct objc_super {

__unsafe_unretained id receiver;

__unsafe_unretained Class super_class;

};

结构体有两个成员,第一个成员是 receiver, 类似于上面的 objc_msgSend函数第一个参数self 。第二个成员是记录当前类的父类是什么。

解惑:这个题目主要是考察关于objc中对 self 和 super 的理解。

self 是类的隐藏参数,指向当前调用方法的这个类的实例。

而 super 是一个 Magic Keyword, 它本质是一个编译器标示符,和 self 是指向的同一个消息接受者。

上面的例子不管调用[self class]还是[super class],接受消息的对象都是当前 Son *xxx 这个对象。而不同的是,super是告诉编译器,调用 class 这个方法时,要去父类的方法,而不是本类里的。

Class实际上是存在于内存中的,可以看成是一个特殊的对象 对一个子类发消息,如果子类中找不到对应的方法,会自动向上搜索,直到根类

[super class];在哪个类里写,哪个类就是接收消息的对象 self 指在本类中找到方法 让本类去执行 super 是在编译的时候 让机器去父类或者父类的父类找方法 然后还是本类执行 所以 【super class】 是在父类的父类 也就是NSObject中 找到了这个方法 但是 执行的时候 都是Son 执行的 所以 打印结果就是一样的(个人理解)

具体多看上面的连接,熟能生巧。

待补充

iOS单元测试简单使用

单元测试一般我们都不会主动去用,除非有这方面需求,这个东西用起来还是蛮好的。

我们可以对某一个功能进行单独测试,不用整体运行

只需要在单元测试 _Tests.m 加入我们自定义的方法和要测试的内容就可以了。

最简单的例子:

按快捷键Command + U进行单元测试,这个快捷键是全部测试。testExample方法中输入
NSLog(@”自定义测试testExample”);
int a= 3;
XCTAssertTrue(a == 0,”a 不能等于 0”);

自带OCUnit的测试用例最常用的方法有三个:

    • (void)setUp:每个test方法执行前调用
    • (void)tearDown:每个test方法执行后调用
    • (void)testXXX:命名为XXX的测试方法

我们也可以自己起个方法名字 - (void)xxxx 里面放入我们想要测试的功能。

比如你可以单独测试某个网络接口是否可以使用,不用再一个一个页面进行跳转然后进行测试。

注意:相应的文件链接地址也要在单元测试里配置下。

当然也有一些高级的作用,比如自动发布、自动测试(特别在一些大的项目,以防止程序被误改或引起新的问题)。

这个可以有空研究下…

两篇不错的文章:http://www.jianshu.com/p/8bbec078cabe
http://www.cocoachina.com/industry/20130724/6667.html

实现一个自己的NSNotificationCenter

我一直觉得代码会随着时间的久更新变动的快,但是思想这个东西是越经过时间越经典的一个东西。

如何获取一些好的思想呢?多看别人的代码 多去总结和思考 多交流 分享 面试 等等 都是获取一些好的想法的途径。

接下来进入正题:

如何来实现一个自己的NSNotificationCenter?由于我们看不到源码 所以也不知道苹果具体是怎么实现的。

但是大致肯定的是:系统的通知中心,就是用观察者模式实现的

NSNotificationCenter是一个单例模式,保存了所有注册的观察者

当有消息要发送,遍历观察者列表,给对应的观察者转发消息 。

具体代码实现请看我的github地址:

https://github.com/jiecoding/DIYNSNotificationCenter

下面的是简单回顾下系统的通知中心(高手可以直接跳过),对于有什么好的建议请及时提出来,谢谢!

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationSelector) name:@"notificationName" object:nil];

NSNotificationCenter消息通信机制介绍(KVO)

作用:NSNotificationCenter是专门供程序中不同类间的消息通信而设置的.

注册通知:即要在什么地方接受消息
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mytest:) name:@” mytest” object:nil];
参数介绍:
addObserver: 观察者,即在什么地方接收通知;
  selector: 收到通知后调用何种方法;
  name: 通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。
发送通知:调用观察者处的方法。
[[NSNotificationCenter defaultCenter] postNotificationName:@”mytest” object:searchFriendArray];
参数:
postNotificationName:通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。
object:传递的参数
注册方法的写法:

  • (void) mytest:(NSNotification*) notification
    {
    id obj = [notification object];//获取到传递的对象
    }

附:注册键盘升启关闭消息

//键盘升起 [[NSNotificationCenter……
简单的使用参照:http://my.oschina.net/gexun/blog/385799

上面简单看了下NSNotificationCenter的使用和简单构成原理。

然后接下来我们思考下,如果我们自己实现应该如何做?

第一步 先创建一个单例 ,然后写添加监听和 发送广播

  • (DIYNotificationSingle )sharedManager
    {
    static DIYNotificationSingle
    ManagerInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
    ManagerInstance = [[self alloc] init];
    
    });
    return ManagerInstance;
    }
  • (void)diyAddObserver:(id)observer selector:(SEL)aSelector name:(nullable NSString *)aName object:(nullable id)anObject
    {

    Entity *entity = [[Entity alloc] init];
    entity.observer = observer;
    entity.aSelector = aSelector;
    entity.notificationName = aName;
      if(!_observers)
      {
          _observers = [[NSMutableArray alloc] init];
      }
    
    [_observers addObject:entity];
    

    }

  • (void)diyPostNotificationName:(NSString )aName object:(nullable id)anObject
    {
    for (Entity
    observer in _observers)
    {

    [observer.observer performSelector:observer.aSelector withObject:nil];
    

    }

}

  • (void)diyRemoveObserver:(id)observer name:(nullable NSString *)aName object:(nullable id)anObject
    {
    for (int i = 0; i < _observers.count ; i++){

    Entity *observerE = [_observers objectAtIndex:i];
    if([observerE.observer isEqual:observer]){
        [_observers removeObjectAtIndex:i];
    }
    

    }
    NSLog(@”remove:%@”,_observers);

}
关于消息处理方法runtime等 可以预览下 http://www.cnblogs.com/buro79xxd/archive/2012/04/10/2440074.html