日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

詳解iOS?實現一對多代理方案_IOS

作者:執筆續春秋 ? 更新時間: 2022-04-03 編程語言

實現方案一

利用可變數組。 簽協議方需要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 等等, 實現方式大同小異。

原文鏈接:https://juejin.cn/post/7044812578735783944

欄目分類
最近更新