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

网站程序开发制作十大品牌我们公司在做网站推广

网站程序开发制作十大品牌,我们公司在做网站推广,全球最大的电商平台,做网站项目后台的__block可以用于解决block内部无法修改auto变量值的问题 __block不能修饰全局变量、静态变量(static) 编译器会将__block变量包装成一个对象 调用的是,从__Block_byref_a_0的指针找到 a所在的内存,然后修改值 第一层拷贝&…
  • __block可以用于解决block内部无法修改auto变量值的问题

  • __block不能修饰全局变量、静态变量(static)

    • 编译器会将__block变量包装成一个对象

调用的是,从__Block_byref_a_0的指针找到 a所在的内存,然后修改值
Pasted image 20230726145216.png

第一层拷贝(block)

block中的第一层拷贝其实已经讲过了——_Block_copy将block从栈拷贝到堆

第二层拷贝(捕获变量的内存空间)

Pasted image 20230725201046.png

在函数声明时会传__main_block_desc_0_DATA结构体,在里面又会去调用__main_block_copy_0函数,__main_block_copy_0里面会调用_Block_object_assign——这就是第二层拷贝的调用入口。
根据flags & BLOCK_ALL_COPY_DISPOSE_FLAGS进到不同分支来处理捕获到的变量
Pasted image 20230726154645.png

此时捕获到的变量是被__block修饰的BLOCK_FIELD_IS_BYREF类型,就会调用*dest = _Block_byref_copy(object);

static struct Block_byref *_Block_byref_copy(const void *arg) {// 临时变量的保存struct Block_byref *src = (struct Block_byref *)arg;if ((src->forwarding->flags & BLOCK_REFCOUNT_MASK) == 0) {// src points to stack// 用原目标的大小在堆区生成一个Block_byrefstruct Block_byref *copy = (struct Block_byref *)malloc(src->size);copy->isa = NULL;// byref value 4 is logical refcount of 2: one for caller, one for stackcopy->flags = src->flags | BLOCK_BYREF_NEEDS_FREE | 4;// 原来的区域和新的区域都指向同一个对象,使得block具备了修改能力copy->forwarding = copy; // patch heap copy to point to itselfsrc->forwarding = copy;  // patch stack to point to heap copycopy->size = src->size;if (src->flags & BLOCK_BYREF_HAS_COPY_DISPOSE) {// Trust copy helper to copy everything of interest// If more than one field shows up in a byref block this is wrong XXXstruct Block_byref_2 *src2 = (struct Block_byref_2 *)(src+1);struct Block_byref_2 *copy2 = (struct Block_byref_2 *)(copy+1);copy2->byref_keep = src2->byref_keep;copy2->byref_destroy = src2->byref_destroy;if (src->flags & BLOCK_BYREF_LAYOUT_EXTENDED) {struct Block_byref_3 *src3 = (struct Block_byref_3 *)(src2+1);struct Block_byref_3 *copy3 = (struct Block_byref_3*)(copy2+1);copy3->layout = src3->layout;}// 第三层拷贝(*src2->byref_keep)(copy, src);}else {// Bitwise copy.// This copy includes Block_byref_3, if any.memmove(copy+1, src+1, src->size - sizeof(*src));}}// already copied to heapelse if ((src->forwarding->flags & BLOCK_BYREF_NEEDS_FREE) == BLOCK_BYREF_NEEDS_FREE) {latching_incr_int(&src->forwarding->flags);}return src->forwarding;
}

用原目标name的大小在堆区生成一个Block_byref
copy->forwarding = copy; & src->forwarding = copy;——原来的区域和新的区域都指向同一个对象,使得block具备了修改能力
(* src2->byref_keep)(copy, src)开始第三层拷贝

第三层拷贝(拷贝对象)

(*src2->byref_keep)(copy, src)点进去会来到Block_byref结构来,而byref_keepBlock_byref的第5个属性

struct Block_byref {void * __ptrauth_objc_isa_pointer isa;struct Block_byref *forwarding;volatile int32_t flags; // contains ref countuint32_t size;
};struct Block_byref_2 {// requires BLOCK_BYREF_HAS_COPY_DISPOSEBlockByrefKeepFunction byref_keep;BlockByrefDestroyFunction byref_destroy;
};struct Block_byref_3 {// requires BLOCK_BYREF_LAYOUT_EXTENDEDconst char *layout;
};

Pasted image 20230726154841.png

第5位就等于byref_keep,所以在第二层拷贝时会调用__Block_byref_id_object_copy_131

static void __Block_byref_id_object_copy_131(void *dst, void *src) {_Block_object_assign((char*)dst + 40, *(void * *) ((char*)src + 40), 131);
}
static void __Block_byref_id_object_dispose_131(void *src) {_Block_object_dispose(*(void * *) ((char*)src + 40), 131);
}

这个(char*)dst + 40看到__Block_byref_name_0就顿悟了,刚好取得变量name对象。

struct __Block_byref_name_0 {void *__isa;
__Block_byref_name_0 *__forwarding;int __flags;int __size;void (*__Block_byref_id_object_copy)(void*, void*);void (*__Block_byref_id_object_dispose)(void*);NSString *name;
};

_Block_object_assign在对BLOCK_FIELD_IS_OBJECT情况时会做出如下操作:

	case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT:case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK:/*******// copy the actual field held in the __block container// Note this is MRC unretained __block only. // ARC retained __block is handled by the copy helper directly.__block id object;__block void (^object)(void);[^{ object; } copy];********/*dest = object;break;

block捕获的外接变量由ARC自动管理,捕获到name进行拷贝
block中有三层拷贝:拷贝block、拷贝捕获变量的内存地址、拷贝对象

_ Block_object_dispose

void _Block_object_dispose(const void *object, const int flags) {switch (os_assumes(flags & BLOCK_ALL_COPY_DISPOSE_FLAGS)) {case BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK:case BLOCK_FIELD_IS_BYREF:// get rid of the __block data structure held in a Block_Block_byref_release(object);break;case BLOCK_FIELD_IS_BLOCK:_Block_release(object);break;case BLOCK_FIELD_IS_OBJECT:_Block_release_object(object);break;case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT:case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK:case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK:case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK  | BLOCK_FIELD_IS_WEAK:break;default:break;}
}
// API entry point to release a copied Block
void _Block_release(const void *arg) {struct Block_layout *aBlock = (struct Block_layout *)arg;if (!aBlock) return;if (aBlock->flags & BLOCK_IS_GLOBAL) return;if (! (aBlock->flags & BLOCK_NEEDS_FREE)) return;if (latching_decr_int_should_deallocate(&aBlock->flags)) {_Block_call_dispose_helper(aBlock);_Block_destructInstance(aBlock);free(aBlock);}
}
  • 如果是释放对象就什么也不做(自动释放)
  • 如果是__block修饰,就将指向指回原来的区域并使用free释放
http://www.zhongyajixie.com/news/46581.html

相关文章:

  • 哪个网站做logo赚钱营销管理
  • 群晖 做网站 Java网店推广方式有哪些
  • 网站开发 原理百度竞价员
  • 西宁做网站制作的公司佛山网站建设制作
  • 建设网站公司哪里好相关的热搜问题解决方案在线教育
  • 做网站怎么备案百度提交入口网址在哪
  • 网站管理员可控的关键节点关键路径
  • 诸城网站建设网站及搜索引擎优化建议
  • 网站移动页面怎么做杭州关键词推广优化方案
  • 上海网站开发工程师招聘网seo公司后付费
  • vue消息推送和系统通知排名优化课程
  • 公司网站案例展示360关键词推广
  • 越秀区做网站宁波建站模板系统
  • 做图片的网站优化排名 生客seo
  • 怎么做二维码让别人扫码进入网站国际新闻快报
  • 网站开发后乙方把源代码交给甲方app营销十大成功案例
  • 网站建设金手指排名霸屏seo外包服务项目
  • 新手网站设计看哪本书教育培训网站大全
  • 合肥网站空间手机清理优化软件排名
  • 做网站反复修改上海网络推广团队
  • 泰安市委常委名单广东seo推广费用
  • 桓台网站制作宁波营销型网站建设优化建站
  • 网站seo内容优化整合营销是什么
  • 企业网站带后台模板关键词排名规则
  • 用爱奇艺会员做视频网站违法吗网络推广工作能长久吗
  • 市住房和城乡建设局网站个人博客网站怎么做
  • 58企业网站如何做一般网络推广应该怎么做
  • php网站开发中如何今天的国内新闻
  • 松江网站制作百度竞价最低点击一次多少钱
  • 郑州做网站哪家好熊掌号竞价广告点击软件