//
// WSGlobalCallbackMgr.h
// OCTest
//
// Created by Sammy Lan on 2020/12/1.
// Copyright © 2020 Sammy Lan. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef void (*WSCallbackT)(void *arg);
#define WSTaskPriorityDefault (long)(-1)
struct WSTaskInfo {
char * key;
unsigned long priority; //优先级,值越小优先级越高,用于确定任务的执行先后顺序,如果不需要确定的顺序执行,可以使用WSTaskPriorityDefault
WSCallbackT callback;
};
#define SECTION_KEY(key) "__" #key ".ws"
#define RUN_FUNCTION_ON_STAY_WITH_PRIORITY(key,priority) \
static void _ram##key(void *); \
__attribute__((used, section("__DATA," SECTION_KEY(key)))) static const struct WSTaskInfo __F##key = (struct WSTaskInfo){(char *)(&#key), priority, (void *)(&_ram##key)}; \
static void _ram##key(void *arg)
#define RUN_FUNCTION_ON_STAY(key) RUN_FUNCTION_ON_STAY_WITH_PRIORITY(key,WSTaskPriorityDefault)
//kMain: 在main函数开始执行
//kStartup: 在application:didFinishLaunchingWithOptions: 执行
//kAppeared: 在首页渲染完毕后执行
//kLogin: 在登录完成后执行
//kLoginEx: 在登录完成后且首页渲染完毕后执行
NS_ASSUME_NONNULL_BEGIN
@interface WSGlobalCallbackMgr : NSObject
+ (instancetype)sharedInstance;
- (void)runFunctionOnState:(char const *)state arg:(nullable void *)arg;
@end
NS_ASSUME_NONNULL_END
//
// WSGlobalCallbackMgr.m
// OCTest
//
// Created by Sammy Lan on 2020/12/1.
// Copyright © 2020 Sammy Lan. All rights reserved.
//
#import "WSGlobalCallbackMgr.h"
#import <dlfcn.h>
#include <mach-o/loader.h>
#include <mach-o/getsect.h>
#include<mach-o/dyld.h>
#include<mach/mach.h>
#ifndef IMPL_SINGLETON
#define IMPL_SINGLETON(className) \
+(instancetype)sharedInstance \
{ \
static className *sharedInstance = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
sharedInstance = [[className alloc] init]; \
}); \
return sharedInstance; \
}
#endif
static NSString *configuration = @"";
@interface WSGlobalCallbackMgr ()
{
}
@end
@implementation WSGlobalCallbackMgr
IMPL_SINGLETON(WSGlobalCallbackMgr);
- (void)runFunctionOnState:(char const *)state arg:(nullable void *)arg;
{
int *ptr = nullptr;
if (sizeof(ptr) == 8) {
[self loadSectionData64:state arg:arg];
} else {
[self loadSectionData32:state arg:arg];
}
}
- (void)loadSectionData64:(char const *)state arg:(nullable void *)arg;
{
static mach_header_64 * s_machHeader;
if (s_machHeader == nullptr) {
Dl_info info;
dladdr((__bridge const void *)(configuration), &info);
s_machHeader = (struct mach_header_64 *)info.dli_fbase;
}
intptr_t slide = _dyld_get_image_vmaddr_slide(1);
UInt64 byteCount = 0;
WSTaskInfo *taskInfo = (WSTaskInfo *)(WSTaskInfo *) (getsectdatafromheader_64(s_machHeader, "__DATA",state , &byteCount) + slide);;
auto counter = byteCount / sizeof(WSTaskInfo);
for (NSUInteger idx = 0; idx < counter; ++idx) {
WSTaskInfo &item = taskInfo[idx];
item.callback(arg);
}
}
- (void)loadSectionData32:(char const *)state arg:(nullable void *)arg;
{
static mach_header * s_machHeader;
if (s_machHeader == nullptr) {
Dl_info info;
dladdr((__bridge const void *)(configuration), &info);
s_machHeader = (struct mach_header *)info.dli_fbase;
}
intptr_t slide = _dyld_get_image_vmaddr_slide(1);
uint32_t byteCount = 0;
WSTaskInfo *taskInfo = (WSTaskInfo *)(WSTaskInfo *) (getsectdatafromheader(s_machHeader, "__DATA",state , &byteCount) + slide);;
auto counter = byteCount / sizeof(WSTaskInfo);
for (NSUInteger idx = 0; idx < counter; ++idx) {
WSTaskInfo &item = taskInfo[idx];
item.callback(arg);
}
}
@end
RUN_FUNCTION_ON_STAY(kStartup)
{
NSLog(@"File: %s,Line: %d",__FILE__,__LINE__);
}
https://blog.csdn.net/ios8988/article/details/89510599
网友评论