当前位置: 首页 > news >正文

wordpress hotnews/武汉本地seo

wordpress hotnews,武汉本地seo,做外贸从哪些网站获取客户,公共服务平台网站建设方案标签:开场白Block基本概念中间态转换方法Block编译后结果分析Block运行时状态与编译状态对比开场白Object-C语言是对C语言的扩展,所以将OC源码进行编译的时候,会将OC源码会被转换成C\C,所以想了解OC源码的实现细节,还是…

标签:

开场白

Block基本概念

中间态转换方法

Block编译后结果分析

Block运行时状态与编译状态对比

开场白

Object-C语言是对C语言的扩展,所以将OC源码进行编译的时候,会将OC源码会被转换成C\C++,所以想了解OC源码的实现细节,还是需要手动编译成中间状态进行观察。

命令1:

clang -rewrite-objc main.m

如果Xcode版本较高,可能会出现报错:

./block_VC.h:9:9: fatal error: 'UIKit/UIKit.h' file not found

此时可尝试另一个命令:

clang -x objective-c -rewrite-objc -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk main.m

命令好长,每次输入这么长的指令很麻烦,此时可以考虑使用命令别名:alias

用法如下:https://www.cnblogs.com/zhou--fei/p/10224000.html

Block的基本概念

_NSConcreteGlobalBlock 全局的静态 block,不会访问任何外部变量。

_NSConcreteStackBlock 保存在栈中的 block,当函数返回时会被销毁。

_NSConcreteMallocBlock 保存在堆中的 block,当引用计数为 0 时会被销毁。

堆中的 block何时转换:

1.调用copy方法时

2.从一个函数返回时

3.将block传入dispatch等系统IPA参数block或者传递给带有usingBlock的Cocoa框架函数时。

4.将block赋给带有__strong修饰符的id类型或者Block类型时。

Block类型变换方式

1.没有捕获任何局部变量的block为_NSConcreteGlobalBlock,它以static函数的形式存储在代码区

2.捕获了局部变量的block为_NSConcreteStackBlock

3.当_NSConcreteStackBlock出现上面四种情况时,会变成_NSConcreteMallocBlock。(注意此时是调用了Block_Copy函数后)

Block编译后结果分析

基本类型变量

OC源码:

NSInteger age = 10;

void(^completeBlock)(NSString *) = ^(NSString *name) {

NSString *info = [NSString stringWithFormat:@"name:%@ - age:%d",name,age];

NSLog(@"%@",info);

};

completeBlock(@"jack");

编译后的C\C++源码:

// __block_impl为block的基础struct

//1.*isa:当前block对象所属的类型(注意:在OC语言中带有isa指针的都是对象)

//2.Flags:标示位,当类型为NSConcreteMallocBlock时,表示需要ARC内存管理,其他默认不需要内存管理

//3.Reserved:预留标示位,暂时不管它

//4.block的实际static内部函数地址指针

struct __block_impl {

void *isa;

int Flags;

int Reserved;

void *FuncPtr;

};

// __main_block_impl_0为block的最终struct

//1.impl:为上面的__block_impl结构体实例

//2.Desc:为block的描述结构体__main_block_desc_0,里面包含了block结构体的信息描述,在下面讲解

//3.age:从外面补货的变量,block采用的方式是直接在block实例中定义一个变量,将捕获的值赋给它

//4.__main_block_impl_0:为block结构体的构造函数,参数中包含从外面捕获的变量值

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

NSInteger age;

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, NSInteger _age, int flags=0) : age(_age) {

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

};

//__main_block_func_0为block具体实现的函数载体,具体的block的任务实现在此函数内

//参数:1是block的实例指针,2是block的外部传参name

static void __main_block_func_0(struct __main_block_impl_0 *__cself, NSString *name) {

//从block实例中获取age变量的值

NSInteger age = __cself->age; // bound by copy

//生成字符串NSString *info = [NSString stringWithFormat:@"name:%@ - age:%d",name,age];

NSString *info = ((NSString * _Nonnull (*)(id, SEL, NSString * _Nonnull, ...))(void *)objc_msgSend)((id)objc_getClass("NSString"), sel_registerName("stringWithFormat:"), (NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_83d55e_mi_0, (NSString *)name, (NSInteger)age);

//打印NSLog(@"%@",info);

NSLog((NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_83d55e_mi_1,info);

}

//reserved:保留字0

//Block_size:block实例在内存中占据内存大小

//__main_block_desc_0_DATA:默认desc结构体实例

static struct __main_block_desc_0 {

size_t reserved;

size_t Block_size;

} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};

//main函数

int main(int argc, char * argv[]) {

/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;

NSInteger age = 10;

void(*completeBlock)(NSString *) = ((void (*)(NSString *))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, age));

((void (*)(__block_impl *, NSString *))((__block_impl *)completeBlock)->FuncPtr)((__block_impl *)completeBlock, (NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_83d55e_mi_2);

return UIApplicationMain(argc, argv, __null, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class"))));

}

}

block简单结构布局

struct __block_impl

struct __main_block_impl_0

static void __main_block_func_0

static struct __main_block_desc_0

详细解释见上面的中间编译状态。

block实例中定义了一个age变量,并将外部的age传了过去

__block基本类型变量

OC源码:

__block NSInteger age = 10;

void(^completeBlock)(NSString *) = ^(NSString *name) {

NSString *info = [NSString stringWithFormat:@"name:%@ - age:%d",name,age];

NSLog(@"%@",info);

};

completeBlock(@"jack");

编译后的C\C++源码:

struct __block_impl {

void *isa;

int Flags;

int Reserved;

void *FuncPtr;

};

//age的block变量实例__Block_byref_age

//__isa:age的block变量实例所属的类型

//__forwarding:age的block变量实例的指针

//__flags:变量是否被内存管理标示

//__size:所占内存大小

//age:age变量值

struct __Block_byref_age_0 {

void *__isa;

__Block_byref_age_0 *__forwarding;

int __flags;

int __size;

NSInteger age;

};

//原来的age变量值,变成了__Block_byref_age_0变量指针

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

__Block_byref_age_0 *age; // by ref

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_age_0 *_age, int flags=0) : age(_age->__forwarding) {

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

};

static void __main_block_func_0(struct __main_block_impl_0 *__cself, NSString *name) {

//通过block实例获取变量的指针

__Block_byref_age_0 *age = __cself->age; // bound by ref

NSLog((NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_7acc63_mi_0,name,(age->__forwarding->age));

}

//当block从栈复制到堆上时,会对__Block_byref_age_0变量进行拷贝,也会从栈拷贝到堆上

static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->age, (void*)src->age, 8/*BLOCK_FIELD_IS_BYREF*/);}

//__Block_byref_age_0变量的析构函数,当block实例的引用计数为0时,是否__Block_byref_age_0变量的内存空间

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->age, 8/*BLOCK_FIELD_IS_BYREF*/);}

//desc结构体中新增了copy函数和dispose函数指针

static struct __main_block_desc_0 {

size_t reserved;

size_t Block_size;

void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);

void (*dispose)(struct __main_block_impl_0*);

} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};

int main(int argc, char * argv[]) {

/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;

//block变量实例

__attribute__((__blocks__(byref))) __Block_byref_age_0 age = {(void*)0,(__Block_byref_age_0 *)&age, 0, sizeof(__Block_byref_age_0), 10};

//block实例

void(*completeBlock)(NSString *) = ((void (*)(NSString *))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_age_0 *)&age, 570425344));

((void (*)(__block_impl *, NSString *))((__block_impl *)completeBlock)->FuncPtr)((__block_impl *)completeBlock, (NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_7acc63_mi_1);

return UIApplicationMain(argc, argv, __null, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class"))));

}

}

简单结构布局

struct __block_impl

struct __main_block_impl_0

static void __main_block_func_0

static struct __main_block_desc_0

//新增

struct __Block_byref_age_0

static void __main_block_copy_0(

static void __main_block_dispose_0(

__block NSInteger age = 10;后,在简单布局结构中新增了3项

struct __Block_byref_age_0

static void __main_block_copy_0(

static void __main_block_dispose_0(

__Block_byref_age_0将基本变量转换成__block变量结构体实例指针

__main_block_copy_0和__main_block_dispose_0是对__block变量结构体实例的内存管理方法。

__block变量结构体实例从栈拷贝到堆时,调用方法:__main_block_copy_0

__block变量结构体实例引用计数为0时,调用方法:__main_block_dispose_0

指针类型变量

OC源码:

NSMutableArray *friends = [NSMutableArray array];;

void(^completeBlock)(NSString *) = ^(NSString *name) {

NSLog(@"%@--%@",name,friends);

};

completeBlock(@"jack");

编译后的C\C++源码:

struct __block_impl {

void *isa;

int Flags;

int Reserved;

void *FuncPtr;

};

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

NSMutableArray *friends;

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, NSMutableArray *_friends, int flags=0) : friends(_friends) {

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

};

static void __main_block_func_0(struct __main_block_impl_0 *__cself, NSString *name) {

NSMutableArray *friends = __cself->friends; // bound by copy

NSLog((NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_1b4a2f_mi_0,name,friends);

}

//block实例从栈复制到堆上时,将指针变量引用计数加一

static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->friends, (void*)src->friends, 3/*BLOCK_FIELD_IS_OBJECT*/);}

//block实例引用计数为0时,析构指针变量对象

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->friends, 3/*BLOCK_FIELD_IS_OBJECT*/);}

static struct __main_block_desc_0 {

size_t reserved;

size_t Block_size;

void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);

void (*dispose)(struct __main_block_impl_0*);

} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};

int main(int argc, char * argv[]) {

/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;

NSMutableArray *friends = ((NSMutableArray * _Nonnull (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSMutableArray"), sel_registerName("array"));;

void(*completeBlock)(NSString *) = ((void (*)(NSString *))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, friends, 570425344));

((void (*)(__block_impl *, NSString *))((__block_impl *)completeBlock)->FuncPtr)((__block_impl *)completeBlock, (NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_1b4a2f_mi_1);

return UIApplicationMain(argc, argv, __null, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class"))));

}

}

简单结构布局

struct __block_impl

struct __main_block_impl_0

static void __main_block_func_0

static struct __main_block_desc_0

static void __main_block_copy_0(

static void __main_block_dispose_0(

block实例中定义了一个NSMutableArray *friends;指针变量,并通过构造函数将指针传递给block实例

__main_block_copy_0:block实例从栈复制到堆上时,将指针变量引用计数加一

__main_block_dispose_0:block实例引用计数为0时,析构指针变量对象

__block指针类型变量

OC源码:

__block NSMutableArray *friends = [NSMutableArray array];;

void(^completeBlock)(NSString *) = ^(NSString *name) {

NSLog(@"%@--%@",name,friends);

};

completeBlock(@"jack");

编译后的C\C++源码:

struct __block_impl {

void *isa;

int Flags;

int Reserved;

void *FuncPtr;

};

//__Block_byref_friends_0结构体实例中包含了friends指针

//并且多了__Block_byref_id_object_copy函数:对friends进行copy

//多了__Block_byref_id_object_dispose函数:对friends进行析构

struct __Block_byref_friends_0 {

void *__isa;

__Block_byref_friends_0 *__forwarding;

int __flags;

int __size;

void (*__Block_byref_id_object_copy)(void*, void*);

void (*__Block_byref_id_object_dispose)(void*);

NSMutableArray *friends;

};

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

__Block_byref_friends_0 *friends; // by ref

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_friends_0 *_friends, int flags=0) : friends(_friends->__forwarding) {

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

};

static void __main_block_func_0(struct __main_block_impl_0 *__cself, NSString *name) {

__Block_byref_friends_0 *friends = __cself->friends; // bound by ref

NSLog((NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_252d0c_mi_0,name,(friends->__forwarding->friends));

}

//block实例从栈复制到堆上时,__block变量结构体实例将指针变量引用计数加一,同时__block变量结构体实例内的NSMutableArray *friends变量也递归加一

static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)&dst->friends, (void*)src->friends, 8/*BLOCK_FIELD_IS_BYREF*/);}

//block实例引用计数为0时,__block变量结构体实例被析构,同时__block变量结构体实例内的NSMutableArray *friends变量也递归析构

static void __main_block_dispose_0(struct __main_block_impl_0*src) {_Block_object_dispose((void*)src->friends, 8/*BLOCK_FIELD_IS_BYREF*/);}

static struct __main_block_desc_0 {

size_t reserved;

size_t Block_size;

void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);

void (*dispose)(struct __main_block_impl_0*);

} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};

int main(int argc, char * argv[]) {

/* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool;

__attribute__((__blocks__(byref))) __Block_byref_friends_0 friends = {(void*)0,(__Block_byref_friends_0 *)&friends, 33554432, sizeof(__Block_byref_friends_0), __Block_byref_id_object_copy_131, __Block_byref_id_object_dispose_131, ((NSMutableArray * _Nonnull (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSMutableArray"), sel_registerName("array"))};;

void(*completeBlock)(NSString *) = ((void (*)(NSString *))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_friends_0 *)&friends, 570425344));

((void (*)(__block_impl *, NSString *))((__block_impl *)completeBlock)->FuncPtr)((__block_impl *)completeBlock, (NSString *)&__NSConstantStringImpl__var_folders_4y_ks8945f50k51_0j95ytw7ss80000gn_T_main_252d0c_mi_1);

return UIApplicationMain(argc, argv, __null, NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class"))));

}

}

简单结构变量

struct __block_impl

struct __main_block_impl_0

static void __main_block_func_0

static struct __main_block_desc_0

static void __main_block_copy_0(

static void __main_block_dispose_0(

//新增

struct __Block_byref_age_0

和__block普通变量一样,出现了__Block_byref_age_0结构体

__Block_byref_friends_0结构体实例中包含了friends指针

并且多了__Block_byref_id_object_copy函数:对friends进行copy

多了__Block_byref_id_object_dispose函数:对friends进行析构

同时在函数__main_block_copy_0和__main_block_dispose_0中,出现的也是对__Block_byref_age_0结构体的调用。它是在将__Block_byref_age_0结构体析构之前,先析构friends对象。

Block编译中间态与运行时状态对比

利用lldb打印出来的结果

局部自由变量

//局部变量

__block NSMutableArray *friends = [NSMutableArray array];;

void(^completeBlock)(NSString *) = ^(NSString *name) {

NSLog(@"%@--%@",name,friends);

};

(lldb) expression -P 5 -- completeBlock

(void (^)(NSString *)) $2 = 0x000000010a061130 {

__isa = __NSMallocBlock__

__flags = -1023410170

__reserved = 0

__FuncPtr = 0x000000010a061130 (iOS_KnowledgeStructure`__main_block_invoke at main.m:19) {}

}

利用clang转换后的C\C++源码

struct __main_block_impl_0 {

struct __block_impl impl;

struct __main_block_desc_0* Desc;

__Block_byref_friends_0 *friends; // by ref

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_friends_0 *_friends, int flags=0) : friends(_friends->__forwarding) {

impl.isa = &_NSConcreteStackBlock;

impl.Flags = flags;

impl.FuncPtr = fp;

Desc = desc;

}

};

证明clang编译器和llvm编译器编译后的结果有出入。发现isa指针不一致。

编译后的为:impl.isa = &_NSConcreteStackBlock;

运行时的为:__isa = __NSMallocBlock__

原因是block类型转换情况4:“将block赋给带有__strong修饰符的id类型或者Block类型时。”

注意:

_NSConcreteMallocBlock一般不会在源码中出现,它通常在block copy到堆时出现,变化的源码:

static void *_Block_copy_internal(const void *arg, const int flags) {

struct Block_layout *aBlock;

const bool wantsOne = (WANTS_ONE & flags) == WANTS_ONE;

// 1

if (!arg) return NULL;

// 2

aBlock = (struct Block_layout *)arg;

// 3

if (aBlock->flags & BLOCK_NEEDS_FREE) {

// latches on high

latching_incr_int(&aBlock->flags);

return aBlock;

}

// 4

else if (aBlock->flags & BLOCK_IS_GLOBAL) {

return aBlock;

}

// 5

struct Block_layout *result = malloc(aBlock->descriptor->size);

if (!result) return (void *)0;

// 6

memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first

// 7

result->flags &= ~(BLOCK_REFCOUNT_MASK); // XXX not needed

result->flags |= BLOCK_NEEDS_FREE | 1;

// 8

result->isa = _NSConcreteMallocBlock;

// 9

if (result->flags & BLOCK_HAS_COPY_DISPOSE) {

(*aBlock->descriptor->copy)(result, aBlock); // do fixup

}

return result;

}

标签:

来源: https://www.cnblogs.com/zhou--fei/p/10224049.html

http://www.lbrq.cn/news/1057195.html

相关文章:

  • 沈阳企业定制网站建设/最新引流推广方法
  • 做网站是什么软件/淘宝关键词排名优化技巧
  • 泰州网站制作推广/企业网
  • 我自己做网站/焊工培训班
  • wordpress qq在线聊天/网站设计优化
  • 用tomcat做网站/plc培训机构哪家最好
  • 专做校园购物网站/农产品网络营销
  • 网上做网站怎么赚钱/广州百度竞价托管
  • 合肥装饰公司做的好的网站/利于seo的建站系统有哪些
  • 工商管理局注册查询/谷歌seo详细教学
  • 网站设计团队/今天实时热搜榜排名
  • 微信链接网页网站制作/seo薪酬水平
  • 商城网站建设方案书/南宁seo手段
  • 网站定位与功能分析/武汉seo认可搜点网络
  • 新疆网站开发哪家好/抖音seo点击软件排名
  • 张掖网站建设培训/seo的名词解释
  • 35互联做的网站后台怎样登录/网络推广专员是做什么的
  • wordpress 换数据库/杭州最好的seo公司
  • 网站权重多少4/谷歌浏览器中文手机版
  • 网站建设的整个流程图/dz论坛如何seo
  • 建设银行短信带网站/冯耀宗seo
  • 邯郸网站建设维护/武威网站seo
  • 个人网站搭建平台/重庆网站网络推广
  • 中企动力科技做什么的/重庆百度seo排名
  • 湖南网站设计企业/深圳谷歌网络推广公司
  • 做网站的公司/微信推广引流加精准客户
  • 有没有清仓处理的网站/google搜索引擎免费入口
  • 上海网站建设备案号怎么恢复/一站式网络营销
  • 怎么做产品的网站/百度推广助手
  • 网站建设与推广实训小结/搜索引擎收录查询
  • 【数据结构与算法】刷题篇——环形链表的约瑟夫问题
  • FastDeploy2.0:报qwen2.embed_tokens.weight
  • leetcode-python-删除链表的倒数第 N 个结点
  • linux定时器管理 timer_*系统调用及示例
  • Python 基础语法(二):流程控制语句详解
  • 【学习笔记】Manipulate-Anything(基于视觉-语言模型的机器人自动化操控系统)