美文网首页读书笔记iOS Developer
kkbox-ios-dev笔记(五) - Block/Not

kkbox-ios-dev笔记(五) - Block/Not

作者: 百草纪 | 来源:发表于2017-03-17 21:15 被阅读26次

    Blocks

    什么时候用Blocks?什么时候用代理?

    • 通常的区分方式:如果一个方法或函数的调用只有单一的回调,那么使用block,如果可能会有多个不同的回调,那么就使用代理。
    • 这样做的好处是:当一个方法或函数调用会有多种回调的时候,很有可能会有某些回调没有必要实现。代理可以用@required@optional关键字做区分;用block处理回调,就会很难区分某个block是否是必须实现的:在Xcode6.3之前,OC 并没有nullablenonnull等关键字,让我们知道某些方法、某些属性要传入的block可不可以是nil,我们也往往搞不清楚在这些地方传入nil,会不会发生什么危险的事情。

    __block关键字

    • block里面如果使用了在block之外的变量,会将这份变量先复制一份再使用,也就是说,在没有特别宣告的状况下,对我们目前所在的block来说,所有外部变量都是只读取,不能更改。至于block里面用到的 OC 对象,则只会被retain一次。如果想要改变该变量,则需要在该变量前面加上__block关键字。

    __weak关键字

    • 假如某个对象的属性是一个block而这个block里面又用到了self,就会遇到循环retain而无法释放内存的问题:self要被释放才会去释放这个属性,单这个属性作为blockretainself,导致self无法被释放。
    • 如果不想让blockself retain起来,就需要使用__weak关键字。

    Notification Center

    • 对象之间可以不必互相知道彼此的存在,也可以相互传递消息、交换资料/状态的机制。

    接受通知

    一个通知分成几个部分:

    • object:发送者,是谁发出了这个通知
    • name:这个通知叫什么名字
    • user info:这个通知还带了哪些额外信息
    • 在 iOS4 之后,我们可以使用addObserverForName: object: queue: usingBlock:这组使用block语法的API订阅通知,由于是传入block,所以我们就不必另外又写一个selector。而remove observer的写法也会不太一样,该block语法的API会回调一个observer对象,是对removeObserver:传入之前拿到的observer对象。如下:
    self.observer = [[NSNotificationCenter defaultCenter]
    
    addObserverForName:NSCurrentLocaleDidChangeNotification
    object:nil
    queue:[NSOperationQueue mainQueue]
    usingBlock:^(NSNotification *note) {
    

    // 处理 locale 改变的状态
    }];

    * `Remove observer`的时候:
    
    ```swift
    [[NSNotificationCenter defaultCenter] removeObserver:self.observ
    

    er];

    ####发送通知
    * 在建立通知对象之后,对通知中心调用`postNotification:`即可。有以下三种方式:
    
    ```swift
    - (void)postNotification:(NSNotification *)notification;
    
    • (void)postNotificationName:(NSString *)aName
      object:(id)anObject;
    • (void)postNotificationName:(NSString *)aName
      object:(id)anObject
      userInfo:(NSDictionary *)aUserInfo;
    
    ####通知与线程
    * 当我们订阅某个通知之后,我们不能保证负责处理通知的`selector`或`block`会在哪个线程执行
    * **这个通知是在哪个线程发出的,负责接受的`selector`或是`block`,就会在哪个线程执行。**
    * 绝大多数的通知都是在主线程发出。
    
    ####Notification Queue
    * 程序可能会在短时间内送出大量的通知,而造成资源浪费或效能问题。
    * `NSNotificationQueue`相当于是通知发送端与通知中心之间的一个缓冲器,这个缓冲器可以让我们暂缓发出的通知,而在一段缓冲期之内,决定我们是否要合并通知。
    
    > * 首先要建立一个`Notification Queue`对象:
    > 
    > ```swift
    > notificationQueue = [[NSNotificationQueue alloc]
    

    initWithNotificationCenter:[NSNotificationCenter defaultCenter]]
    ;

    * 原本:
    
    ```swift
    NSNotification *n = [NSNotification
    
    notificationWithName:@"KKSongInfoDidChangeNotification"
    object:self];
    

    [[NSNotificationCenter defaultCenter] postNotification:n];

    * 改后:
    
    ```swift
    NSNotification *n = [NSNotification
    
    notificationWithName:@"KKSongInfoDidChangeNotification"
    object:self];
    

    [notificationQueue enqueueNotification:n
    postingStyle:NSPostASAP
    coalesceMask:NSNotificationCoalescingOnName | NSNotificationCoalescingOnSender
    forModes:nil];

    * 在这边传入了`NSNotificationCoalescingOnName`和`NSNotificationCoalescingOnSender`,代表的就是请`notification queue`合并名称相同,发送者也相同的通知。

    相关文章

      网友评论

        本文标题:kkbox-ios-dev笔记(五) - Block/Not

        本文链接:https://www.haomeiwen.com/subject/dtyynttx.html