详解iOS 实现一对多代理方案

目录
  • 实现方案一
  • 实现方案二

实现方案一

利用可变数组。 签协议方需要add到代理的数组中, 然后协议遍历数组中的对象,进行分发。
缺点是需要数组对其内部元素是强引用, 需要在合适的地方对其进行释放,否则会有内存泄漏

代理协议的对象.h写法

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@protocol TestSubViewDelegate <NSObject>

- (void)testSendSomeMessageToOther:(NSString *)somethings;

- (void)testSendSome:(NSString *)somethings;

@end

@interface TestSubView : UIView

//@property (nonatomic, weak)id <TestSubViewDelegate>delegate;

@property (nonatomic, strong)NSMutableArray <id<TestSubViewDelegate>>* __nullable delegates;

- (void)addDelegate:(id<TestSubViewDelegate>)delegate;

// 需要在合适的地方销毁对象。
- (void)destory;
@end

NS_ASSUME_NONNULL_END

.m代理协议分发机制

#import "TestSubView.h"

@interface TestSubView ()

@end

@implementation TestSubView

- (instancetype)init {
    if (self = [super init]) {
        self.delegates = [NSMutableArray array];
        
        // 测试,执行
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self test1DelegateAction];
        });
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self test2DelegateAction];
        });
        
    }
    return self;
}

// 测试代理方法分发1
- (void)test1DelegateAction {
    [self.delegates enumerateObjectsUsingBlock:^(id<TestSubViewDelegate>  _Nonnull delegate, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([delegate respondsToSelector:@selector(testSendSomeMessageToOther:)]) {
            [delegate testSendSomeMessageToOther:@"传递的Some"];
        }
    }];
}

// 测试代理分发2
- (void)test2DelegateAction {
    [self.delegates enumerateObjectsUsingBlock:^(id<TestSubViewDelegate>  _Nonnull delegate, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([delegate respondsToSelector:@selector(testSendSome:)]) {
            [delegate testSendSome:@"传递的Some2-"];
        }
    }];
}

- (void)destory {
    [self.delegates removeAllObjects];
    self.delegates = nil;
}

- (void)addDelegate:(id<TestSubViewDelegate>)delegate {
    [self.delegates addObject:delegate];
}

签订代理方1

#import "View1Controller.h"
#import "TestSubView.h"

@interface View1Controller ()<TestSubViewDelegate>

@end

@implementation View1Controller

- (void)viewDidLoad {
    [super viewDidLoad];
    TestSubView *ts = [TestSubView new];
    [ts addDelegate:self];
    [self.view addSubview:ts];
}

#pragma mark - TestSubViewDelegate
- (void)testSendSomeMessageToOther:(NSString *)somethings {
    NSLog(@"%@", somethings);
}

- (void)testSendSome:(NSString *)somethings {
    NSLog(@"%@", somethings);
}
 
@end

签订方2

#import "ViewController.h"
#import "View1Controller.h"
#import "TestSubView.h"

@interface ViewController ()<TestSubViewDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    TestSubView *ts = [TestSubView new];
    [ts addDelegate:self];
    [self.view addSubview:ts];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    View1Controller *vc = [View1Controller new];
    [self presentViewController:vc animated:YES completion:nil];
}

#pragma mark - TestSubViewDelegate
- (void)testSendSomeMessageToOther:(NSString *)somethings {
    NSLog(@"%@", somethings);
}

@end

实现方案二

采用NSPointerArray去声明delegates的数组,这样就可以不用操心管理内存泄漏的问题, 因为NSPointerArray里面的元素都是weak化的。 会随着当前对象释放而释放掉。

还有一些NSHashTable NSMapTable 等等, 实现方式大同小异。

到此这篇关于详解iOS 实现一对多代理方案的文章就介绍到这了,更多相关iOS 一对多代理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • IOS 代理方式实现实例详解

    IOS 代理方式实现 在客户端开发中,经常用到通知.代理.block来实现各个页面之间关联.通知,以一直"盲"的方式实现传递. 代理.block 可以很明确的知道各个界面之间的关联关系.以代理为例,一般的做法如下 : DesViewController *des = [[DesViewController alloc] init];des.delegate = self;[self.navigationController pushViewController:des animated

  • iOS通过代理逆向传值的方式详解

    前言 在iOS开发中,常见的几种逆向传值方式,有代理(delegate).通知(NSNotification),block等等,本文就给大家分析下,如何理解和快速上手代理模式,并以一个简单的逆向传值为案例,看看代理模式是不是很难. 一.代理模式中的几个概念 讲代理模式之前,首先需要弄清楚两个概念:被代理对象和代理对象.并且需要知道它们之间是靠协议关连起来的. 1.被代理对象 被代理对象往往就是真正有做事意图的那个对象,比如卖房子案例中的想卖房子的房主,保姆婴儿案例中想喝奶的婴儿.但是它们自己做不

  • 谈谈iOS中的多继承与多重代理

    前言 多继承和多重代理在swift的语言层面上是不支持的,但我们有时会遇到这样的问题: 类B和C分别继承自A,B1和B2继承自B,C1和C2继承自C.现在我们需要在B1和C1中添加相同的方法,怎么去做?使用继承的话只能在类A中添加,但这样做的结果是基类A会越来越臃肿,最后变成上帝类God Class,维护起来会很困难. 在实现完某个代理后发现,我们还要在其他页面中获取数据.例如,IM消息接收之后要在多个地方做回调,比如显示消息内容页面,改变小红点,显示消息数.即一对多的模式,我们第一反应是用通知

  • iOS Swift创建代理协议的多种方式示例

    前言 本文主要给大家介绍了iOS Swift创建代理协议的各种方式,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 假如有一个类为 LXFView,现在要为这个类创建一个代理协议,我们该如何做呢? 首先,代理协议的命名方式:类名 + Delegatev protocol LXFViewDelegate { func view(_ view: LXFView) } 当我们创建的协议遵守其它协议的情况下,只是这样写并不会报错,接下来我们在LXFView中添加一个代理属性,为避免循环

  • iOS中TableView如何统一数据源代理详解

    前言 TableView 是 iOS 应用程序中非常通用的组件,几乎每一个界面都有一个TableView,而我们许多的代码都和TableView有关系,比如数据展示.更新TableView,一些响应选择事件等,而这些大多都会通过其代理函数来实现,所以在VC中我们通常需要实现大量TableView的代理函数,如下面这样 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat

  • iOS 实现多代理的方法及实例代码

    iOS实现多代理 什么是多代理 用过环信SDK的同学应该对多代理不陌生了,请看下面代码: @method @brief 注册一个监听对象到监听列表中 @discussion 把监听对象添加到监听列表中准备接收相应的事件 @param delegate 需要注册的监听对象 @param queue 通知监听对象时的线程 @result */ - (void)addDelegate:(id<EMChatManagerDelegate>)delegate delegateQueue:(dispatc

  • 详解iOS 实现一对多代理方案

    目录 实现方案一 实现方案二 实现方案一 利用可变数组. 签协议方需要add到代理的数组中, 然后协议遍历数组中的对象,进行分发.缺点是需要数组对其内部元素是强引用, 需要在合适的地方对其进行释放,否则会有内存泄漏 代理协议的对象.h写法 #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @protocol TestSubViewDelegate <NSObject> - (void)testSendSomeMessageToOther

  • 详解iOS中跨页面状态同步方案比较

    由于团队希望项目能够去 CoreData 化,而以往状态同步都是依赖于 CoreData 的NSFetchedResultsController.因此去 CoreData 则必须寻找一种替代方案来进行状态同步. NotificationCenter 状态同步实际是一对多的场景,也就是一个事件可以被多个观察者监听到.而苹果的系统框架自带的 NotificationCenter 正是用来适配这种场景,并且其也是被系统框架本身及我们开发者大面积使用的.用法如下: 定义通知名字,以及需要额外传递信息的

  • 详解Webpack4多页应用打包方案

    前言 学习了 webpack 之后,将自己的博客的前端进行重构,由于自己的博客是多页应用,所以研究了下多页应用的打包方案.在这里把最后配置的成果分享下,不足之处,请指正.(文字不多,全是代码,不是配置教程,所以没有特别详细的写,只是一个参考) 项目地址: https://github.com/Ray-daydayup/MPA-webpack 文件目录结构 项目目录结构 首先先看下我的项目的目录结构 myblog-webpack ├── dist // 打包输出文件夹 ├── src // 源代码

  • 详解iOS自定义UITabBar与布局

    在小编整理过的文章iOS项目基本框架搭建中,我们详细说明了如何对TabBarItem的图片属性以及文字属性进行一些自定义配置.但是,很多时候,我们需要修改TabBarItem的图片和文字属性之外,还需要自定义TabBarItem的位置,这样系统自带的TabBar的样式并不能满足我们的项目需求,所以我们需要对系统的UITabBar进行自定义,以达到我们的项目需求.例如新浪微博App的底部tab的item就无法用自带的TabBarItem进行实现,最中间那个[+]发布微博并不是用来切换tab的,而是

  • 详解IOS如何防止抓包

    目录 抓包原理 防止抓包 一.发起请求之前判断是否存在代理,存在代理就直接返回,请求失败. 二.我们可以在请求配置中清空代理,让请求不走代理 SSL Pinning(AFN+SSL Pinning)推荐 扩展 抓包原理 其实原理很是简单:一般抓包都是通过代理服务来冒充你的服务器,客户端真正交互的是这个假冒的代理服务,这个假冒的服务再和我们真正的服务交互,这个代理就是一个中间者 ,我们所有的数据都会通过这个中间者,所以我们的数据就会被抓取.HTTPS 也同样会被这个中间者伪造的证书来获取我们加密的

  • 详解Vue适时清理keepalive缓存方案

    目录 需求 思考 尝试 1. 手动操作 keep-alive 组件的 cache 数组 2. exclude 大法好 Demo 需求 单页面应用中,用户进入表单填写页面,需要初始化表单内容,填写过程中可能涉及到地图选点或者列表选择等操作,需要到新的页面选择并回调显示. 此时我们需要缓存表单填写页面实例,当退出表单填写或提交完表单内容之后,需要销毁当前表单实例,下次进入重新进行初始化 思考 说到 Vue 缓存,我们肯定首先选择官方提供的缓存方案 keep-alive 内置组件来实现. keep-a

  • 详解IOS UITableViewCell 的 imageView大小更改

    详解IOS UITableViewCell 的 imageView大小更改 实例代码: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCell

  • 详解IOS开发中生成推送的pem文件

    详解IOS开发中生成推送的pem文件 具体步骤如下: 首先,需要一个pem的证书,该证书需要与开发时签名用的一致. 具体生成pem证书方法如下: 1. 登录到 iPhone Developer Connection Portal(http://developer.apple.com/iphone/manage/overview/index.action )并点击 App IDs 2. 创建一个不使用通配符的 App ID .通配符 ID 不能用于推送通知服务.例如,  com.itotem.ip

  • 详解IOS中文件路径判断是文件还是文件夹

    详解IOS中文件路径判断是文件还是文件夹 方法1 + (BOOL)isDirectory:(NSString *)filePath { BOOL isDirectory = NO; [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]; return isDirectory; } 方法2 + (BOOL)isDirectory:(NSString *)filePath { NSNum

  • 详解IOS串行队列与并行队列进行同步或者异步的实例

    详解IOS串行队列与并行队列进行同步或者异步的实例 IOS中GCD的队列分为串行队列和并行队列,任务分为同步任务和异步任务,他们的排列组合有四种情况,下面分析这四种情况的工作方式. 同步任务,使用GCD dispatch_sync 进行派发任务 - (void)testSync { dispatch_queue_t serialQueue = dispatch_queue_create("com.zyt.queue", DISPATCH_QUEUE_SERIAL); dispatch_

随机推荐