Skip to content

Commit

Permalink
修复 iOS 15 下 WKWebView 的 NavigationDelegate 的 block 写入签名崩溃的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
SilverFruity committed Sep 24, 2021
1 parent da7b157 commit 43b2ecf
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
14 changes: 14 additions & 0 deletions OCRunner/RunEnv/MFBlock.m
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,20 @@ BOOL NSBlockHasSignature(id block){
}
void NSBlockSetSignature(id block, const char *typeencode){
struct MFSimulateBlock *blockRef = (__bridge struct MFSimulateBlock *)block;
// ---- 2021.9.24 TODO:
// 针对 WKWebView 的 navigationDelegate 的 block:
// decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
// ios 15 下直接写入 signatureLocation 内存会导致 EXC_BAD_ACCESS 错误,同时此 block 是一个堆 block,使用内存地址直接写入按理说应该是没有问题。不知是对此内存做了内存保护🤔?可是当在调试的时候,使用 lldb 调试器写入该地址,却完全没有问题。
// 目前为了规避崩溃问题,既然不能操作 signature 的地址内存,那就直接覆盖 descriptor 的内存
// ⚠️ 此处存在的问题为:使用 malloc 开辟的内存空间,存在内存泄漏的问题。
struct MFGOSimulateBlockDescriptor *des = malloc(sizeof(struct MFGOSimulateBlockDescriptor));
memcpy(des, blockRef->descriptor, sizeof(struct MFGOSimulateBlockDescriptor));
// 直接 free 原本的 descriptor 的内存会崩溃
// void *before = blockRef->descriptor;
blockRef->descriptor = des;
// free(before);
// ----

void *signatureLocation = blockRef->descriptor;
signatureLocation += sizeof(unsigned long int);
signatureLocation += sizeof(unsigned long int);
Expand Down
9 changes: 9 additions & 0 deletions OCRunnerDemo/OCRunnerDemo/HotPath/ViewController1.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

#import "ViewController.h"
#import <Masonry/Masonry.h>
typedef NS_ENUM(NSInteger, WKNavigationActionPolicy) {
WKNavigationActionPolicyCancel,
WKNavigationActionPolicyAllow,
WKNavigationActionPolicyDownload
};
void cfunctionCallBlock(void (^block)(NSString *)){
if (block) block(@"cfunctionCallBlock");
}
Expand Down Expand Up @@ -95,6 +100,10 @@ - (void)viewDidLoad {
[self receiveStackBlock:^(NSString *str){ NSLog(@"%@",str); }];
cfunctionCallBlock(nil);
cfunctionCallBlock(^(NSString *str){ NSLog(@"%@",str); });
[self ORGviewDidLoad];
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)receiveStackBlock:(void (^)(NSString *))block{
if (block) block(@"receiveStackBlock:");
Expand Down
19 changes: 16 additions & 3 deletions OCRunnerDemo/OCRunnerDemo/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#import "ViewController.h"
#import <Masonry/Masonry.h>
#import <OCRunner/MFBlock.h>
#import <WebKit/WebKit.h>

@interface ShareInstance: NSObject
@property (nonatomic,copy)NSDictionary *cache;
@end
Expand All @@ -34,16 +36,27 @@ - (NSString *)cacheForKey:(NSString *)key{
@end


@interface ViewController ()

@interface ViewController () <WKNavigationDelegate>
@property (nonatomic, strong)WKWebView *webView;
@end

@implementation ViewController


- (void)viewDidLoad {
[super viewDidLoad];

WKWebView *webView = [WKWebView new];
webView.navigationDelegate = self;
[self.view addSubview:webView];
[webView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.height.equalTo(@(150));
make.right.equalTo(self.view);
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom);
}];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)sendStackBlock{
__weak typeof(self) weakSelf = self;
Expand Down

0 comments on commit 43b2ecf

Please sign in to comment.