Catrgory & Extension
- Category 给原有的类扩展特有的方法;
- Extension 可以扩展变量、属性,可以改写属性的读写属性。
- 什么时候使用?
注意,下面的代码示例是在 BLDemo2 当中进行的,即dragonView
如何给类扩充方法呢(自己创建的类,可以直接在里面创建方法很方便。一般使用 Category 都是给看不到源码的库),新创建一个OC文件,类型为 Category ,这里命名为 URL,Class 这里选择 NSString 。
创建出来之后它的命名方式很独特,首先由 .h 和 .m 文件,其次名称是 NSString+URL 。 在新创建的类中创建一个例子(仅仅是举例), .h 文件中:
#import <Foundation/Foundation.h>
@interface NSString (URL)
- (BOOL)isURL;
@end
在 .m 文件中写明方法:
#import "NSString+URL.h"
@implementation NSString (URL)
- (BOOL)isURL
{
if ([self hasPrefix:@"http://"]) {
return YES;
}
return NO;
}
@end
如果以后真的需要判断是不是URL,这样的方法是不行的,还需要通过比如使用正则表达式等方法。
接下来尝试使用 Category 添加的方法,在 ViewController.m 中先导入 #import "NSString+URL.h":
- (void)viewDidLoad {
[super viewDidLoad];
NSString *url = @"www.baidu.com";
if ([url ifURL]) {
NSLog(@"是一个网址");
} else {
NSLog(@"不是一个网址");
}
}
关于 Extension 增加成员变量就更佳地方便,可以直接在 ViewController.m 中操作:
@interface ViewController ()
{
BLDragonView *_dragonView1;
}
// 增加属性就是这样操作
@property(nonatomic, retain)BLDragonView *dragonView;
@end
这样的好处是在 ViewController 这个类中可以在任何地方对 _dragonView1 进行访问。
关于 Extension 改写属性的读写属性,比如在你在一个类的 头文件声明了一个 NSString 类型的变量,并且只是具有 readonly 的特性,对外开发,但是后来你又希望把它改成对内可读写的,这时就可以在实现文件中通过 Extension 改变它的属性。
NSNotification
- 什么是通知?
当发生某件事情之后,将消息发送给所有的对象,对象收到通知后,就会进行相应的操作。代理 “主要” 是一对一的形式,通知一般为1对多。 - 什么时候用?
- 怎么用?
通知的例子可以在 BLDragonView.m 中操作:
- (void)forwardButtonClicked:(id)sender
{
.......
NSDictionary *dic = @{@"name":@"123456", @"time":@"08:30"};
NSNotification *notification = [[NSNotification alloc] initWithName:@"BLDragonViewNotification"
object:nil
user:dic];
[[NSNotificationCenter defaultCenter] postNotification:notification];
// 通知类头一个通知中心,固定在此处发送信息
// 使用异步线程处理通知,在通知多并且希望不阻塞主线程的情况下
[[NSNotificationQueue defaultQueue] enqueueNotification:notification
postingStyle:NSPostNow
coalesceMask:NSNotificationNoCoalescing // 合并类型意思是用什么方式将多个通知合并到一个通知,老师推荐是不合并
forModes:nil] // 模式一般传nil
}
如上通知就发送出去了,现在需要有类来接收通知,我们让 ViewController 类来接收,在 .m 文件中:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self //添加一个观察者 由我自己来检测这个通知
selector:@selector(receiveDragonViewNotification:) // 收到这个通知之后我该做什么
name:@“BLDragonViewNotification:” // 通知的名字,注意这个名字一定是你发出的通知的名字,一一匹配
object:nil // 意思是要接哪一个对象的通知, 如果是接所有对象的话,就填 nil
}
// 然后需要实现接收到通知后的方法
- (void)receiveDragonViewNotification:(NSNotification *)notification
{
NSDictionary *userInfo = notification.userInfo;
NSLog(@"time is %@", [userInfo valueForKey:@"time"]);
}
......
然后运行应用后,点击前进按钮,就会发出通知, ViewController 类酒会接收到通知,然后打印出 key “time” 的键值。
为了显示通知一对多的特性,我们可以将接收通知在别的类中实现,然后实现相应的接收到通知后的方法。
需要注意的一点是,因为接收监听是系统方法,当 ViewController 类被释放之后,这个监听还是没有被释放,并且类没有了就收不到信息了,这样应用继续运行是会导致崩溃的。一般这时,就会运用到 dealloc 方法。如何移出通知呢?在 ViewController.m 中:
- (void)dealloc
{
// [[NSNotificationCenter defaultCenter] removeObserver:self name: object:(id)]; 因为一般这个类中或许需要监听很多,所以方便效率起见,会删除所有,会如下:
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
一定需要注意和掌握这个方法,很多初学者都会只设置监听,却不移除,就会有可能在以后造成应用的崩溃。
还需要注意,通知的发出嗬监听是同步的,意思就是例如当你发出非常多的通知,很多类就会一个一个地去监听,做不了其他事情,如果接受完毕需要10分钟,就代表将阻塞主线程10分钟。(有时候应用用着用着就不动了,这很有可能就是主线程被阻塞掉了)所以当你有非常多的通知需要发送时,尽量不要在主线程中使用,使用异步的方法(看第五个代码段最下面的代码)。最后的效果是一样的,就是不会造成阻塞主线程,一般情况下会使用post,根据具体情况选择。
OC语法完成,ok!(后续学习查漏补缺~)
网友评论