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

做网站和做游戏哪个难wordpress制作小工具

做网站和做游戏哪个难,wordpress制作小工具,网站o2o,查征信怎么查 个人免费查询系列文章目录 文章目录 系列文章目录一、Block是什么二、Block的使用场景1. 异步操作和完成处理器2. 动画3. 集合操作4. 定时器5. 自定义控件的事件处理6.错误处理 三、Block的底层实现1.结构分析2.Block的类型3.Block的copy4.变量捕捉 四、Block的使用细节1.auto变量的生命周期…系列文章目录 文章目录 系列文章目录一、Block是什么二、Block的使用场景1. 异步操作和完成处理器2. 动画3. 集合操作4. 定时器5. 自定义控件的事件处理6.错误处理 三、Block的底层实现1.结构分析2.Block的类型3.Block的copy4.变量捕捉 四、Block的使用细节1.auto变量的生命周期2.__weak修饰变量3.修改局部变量a.定义成全局变量b.定义成static变量c.__block修饰auto变量 4.循环引用 一、Block是什么 在 iOS 开发中Block 是 Objective-C 和 Swift 中非常强大的一个特性用于定义一段可以在任何时候执行的代码块。Block 可以捕获和存储其定义时所处上下文的状态使得它们特别适用于处理异步操作、回调以及集合类的遍历。 Block 类似于其他语言中的匿名函数或闭包。在 Objective-C 中Block 是一种特殊的数据类型可以像对象一样被传递和存储。 在 Objective-C 中你可以这样定义一个 Block //这里myBlock 是一个接受一个整数参数并不返回任何值的 Block。 void (^myBlock)(int) ^(int num) {NSLog(The number is %d, num); };//调用 Block输出: The number is 10 myBlock(10); 如果我们觉得定义一个 Block 很复杂也可以用 typedef 去简化 typedef void (^myBlock)(int);myBlock b1 ^(int num) {NSLog(wml-num:%d,num); };//调用 Block输出: wml-num:100 b1(100);二、Block的使用场景 1. 异步操作和完成处理器 //Block 是处理异步操作如网络请求、文件读写等的理想选择。它们通常用作回调以处理异步操作完成后的数据或状态更新。 [self fetchDataWithURL:url completion:^(NSData *data, NSError *error) {if (error) {NSLog(Failed to fetch data: %, error);} else {NSLog(Data fetched successfully.);// 处理数据} }];2. 动画 Block 在定义动画过程中非常有用特别是使用 UIKit 的动画API时。它可以在动画结束时执行一段代码非常适合于需要在动画序列完成后更新UI的场景。 [UIView animateWithDuration:1.0 animations:^{self.myView.alpha 0.0; } completion:^(BOOL finished) {self.myView.hidden YES; }];3. 集合操作 Block 在处理数组、字典等集合类型时非常有用例如执行过滤、转换、排序等操作。 NSArray *numbers [1, 2, 3, 4, 5]; [numbers enumerateObjectsUsingBlock:^(NSNumber *number, NSUInteger idx, BOOL *stop) {NSLog(Number: %, number);if ([number integerValue] 3) {*stop YES; // 提前终止遍历} }];4. 定时器 Block 也可以用于创建定时器特别是在需要简单任务重复执行时。 dispatch_source_t timer dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC); dispatch_source_set_event_handler(timer, ^{NSLog(Timer fired); }); dispatch_resume(timer);5. 自定义控件的事件处理 Block 允许开发者为自定义控件提供灵活的事件处理机制使得控件的使用更加灵活和强大。 [self.customButton handleTapWithBlock:^{NSLog(Button was tapped!); }];6.错误处理 在执行某些可能会失败的任务时Block 可用于错误处理和恢复策略。 [self performTaskWithCompletion:^(BOOL success, NSError *error) {if (!success) {NSLog(Task failed: %, error);// 处理错误尝试恢复} }];三、Block的底层实现 1.结构分析 我们可以将下面的 oc 代码转换成 c 来看看Block的实现 int main(int argc, const char * argv[]) {int age 20;void (^block)(void) ^{NSLog(age is %d,age);};block();return 0; }关键代码如下 struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;int age;//构造函数(类似于OC中的init方法) _age是外面传入的__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _age, int flags0) : age(_age) {//isa指向_NSConcreteStackBlock 说明这个block就是_NSConcreteStackBlock类型的impl.isa _NSConcreteStackBlock;impl.Flags flags;impl.FuncPtr fp;Desc desc;} };static void __main_block_func_0(struct __main_block_impl_0 *__cself) {int age __cself-age; // bound by copyNSLog((NSString *)__NSConstantStringImpl__var_folders_z2_5qyd6hbj171cdpwjgskps6kc0000gn_T_main_38b1a4_mi_0,age);}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)};int main(int argc, const char * argv[]) {int age 20;void (*block)(void) ((void (*)())__main_block_impl_0((void *)__main_block_func_0, __main_block_desc_0_DATA, age));((void (*)(__block_impl *))((__block_impl *)block)-FuncPtr)((__block_impl *)block);return 0; }static struct IMAGE_INFO { unsigned version; unsigned flag; } _OBJC_IMAGE_INFO { 0, 2 };我们可以将上述代码去除一些类型转换的逻辑进一步简化为 int age 20; void (*block)(void) __main_block_impl_0(__main_block_func_0, __main_block_desc_0_DATA, age);// block的调用 block-FuncPtr(block);用一幅图来表示 2.Block的类型 首先Block 是一个 oc 对象我们可以看到它的继承关系为 Block 有三种基本类型这些类型反映了 Block 在内存中的存储位置以及它如何管理捕获的变量 _NSConcreteGlobalBlock全局 Block不捕获任何外部变量或者只捕获全局变量和静态变量。存储在全局数据区。_NSConcreteStackBlock栈 Block捕获外部变量并存储在栈上。这种 Block 如果需要在定义域之外使用必须进行复制操作将其复制到堆上。_NSConcreteMallocBlock堆 Block是通过复制栈 Block 得到的存储在堆上可以在定义域之外安全使用。 在 MRC 下测试 因为ARC的时候编译器做了很多的优化往往看不到本质。 改为MRC方法 Build Settings 里面的Automatic Reference Counting改为NO。 当 Block 被复制时使用 [block1 copy]它被转移到堆上因此变成了 _NSConcreteMallocBlock 类型。 在 ARC 下测试 在ARC环境下编译器会根据情况自动将栈上的 block 复制到堆上具体来说比如以下情况 block作为函数返回值时将block赋值给__strong指针时block作为Cocoa API中方法名含有usingBlock的方法参数时block作为GCD API的方法参数时 情况总结如下 3.Block的copy 下面测试是在 ARC 的环境下编译器会根据情况自动将栈上的 block 复制到堆上 block作为函数返回值时 Block 属性的声明 copy 最常见且推荐的方式是使用 copy 修饰符。这是因为 Block 默认在栈上创建而使用 copy 可以确保 Block 被复制到堆上从而在其作用域之外也可以安全使用。strong 通常不推荐用于 Block因为这不会将栈上的 Block 复制到堆上可能会导致在 Block 执行时已经不在有效的作用域内。weak 用于避免循环引用特别是当 Block 内部需要引用 self且 self 同时持有这个 Block 时。通常你会在 Block 内部使用一个弱引用的 self而不是将 Block 本身声明为 weak。 4.变量捕捉 对于不同类型的变量有不同的捕捉方式 我们还可以用一个例子来证明变量捕捉的情况 查看底层代码可以看到对于 auto 局部变量是用值传递static 局部变量是用指针传递全局变量则是直接读取 四、Block的使用细节 编译器默认是 ARC 环境所以未作声明的都是 ARC 环境。 1.auto变量的生命周期 在 ARC 环境下auto 变量在出了作用域后会被销毁 interface MyObj : NSObject property (nonatomic ,assign) int age; endimplementation MyObj - (void)dealloc { NSLog(%s,__func__); } endint main(int argc, const char * argv[]) {{MyObj *person [[MyObj alloc]init];person.age 10;}NSLog(----------------);return 0; }结果如下 我们在 Block 中创建一个对象类型的 auto 变量 // 定义block typedef void (^MyBlock)(void);int main(int argc, const char * argv[]) {MyBlock block;{MyObj *obj [[MyObj alloc]init];obj.age 10;block ^{NSLog(---------%d, obj.age);};NSLog(block.class %,[block class]);}NSLog(block销毁);return 0; }运行后我们发现Block 类型为__NSMallocBlock__时延长了变量的生命周期在 Block 销毁后变量才被销毁 我们将 oc 代码转换为 cpp 代码发现变量被捕捉到了 Block 内部 在 MRC 环境下 我们发现 Block 为__NSStackBlock__类型时并没有延长变量的生命周期 我们通过对 Block 进行 copy将类型转换为__NSMallocBlock__时变量的生命周期延长了 2.__weak修饰变量 在 MRC 环境下 当 Block 类型为__NSMallocBlock__时用 __weak修饰变量时Block 持有变量的弱引用不影响变量的生命周期。 左图变量属性为 weak右图属性为 strong。 当 Block 类型为__NSStackBlock__时用 __weak修饰变量时并不起作用。 左图变量属性为 weak右图属性为 strong。 在 ARC 环境下 使用__weak 可以让 Block 对变量由默认的强引用变为弱引用从而影响变量的生命周期。 无论是 MRC 还是 ARC 当 block 为__NSStackBlock__类型时候是在栈空间无论对外面使用的是 strong 还是 weak 都不会对外面的对象进行强弱引用。 当 block 为__NSMallocBlock__类型时候是在堆空间block是内部的_Block_object_assign函数会根据strong或者 weak对外界的对象进行强引用或者弱引用。 3.修改局部变量 我们有三种方式可以在 Block 中去修改一个变量 a.定义成全局变量 b.定义成static变量 c.__block修饰auto变量 4.循环引用 例如下面这段代码在对象中持有了 Block而 Block 又持有了对象的指针出现了循环引用问题导致资源泄露 interface MyObj : NSObject property (nonatomic ,assign) int age; property void (^MyBlock)(void); endimplementation MyObj - (void)dealloc { NSLog(%s,__func__);} endint main(int argc, const char * argv[]) {MyObj *obj [[MyObj alloc] init];obj.MyBlock ^{NSLog(age-%d,obj.age);};return 0; }我们可以用 __weak 来修饰这个在 Block 中用到的指针 用__unsafe_unretained 也可以解决循环引用问题但它是不安全的 __weak不会产生强引用指向的对象销毁时会自动让指针置为nil。__unsafe_unretained不会产生强引用不安全指向的对象销毁时指针存储的地址值不变。 用__block 也可以解决循环引用Block 需要被调用一次来执行 obj nil 总结 在 ARC 环境下最好使用 __weak 来修饰变量避免循环引用。 在 MRC 环境下因为不支持弱指针__weak所以只能是 __unsafe_unretained 或者 __block 来解决循环引用。
http://www.w-s-a.com/news/322741/

相关文章:

  • 水墨 网站源码工装
  • 任丘网站建设服务网站 建设原则
  • 长沙做一个网站要多少钱网站底部备案代码
  • wordpress构建自定义设置页面seo培训学什么
  • 延安有哪些做网站的公司如何建设网站?
  • 网站建设者属于广告经营者吗网站管理程序
  • 网站内容优化方法深圳市宝安区怎么样
  • 视频网站开发视频公司网站制作多少钱
  • 单页简洁手机网站模板购物软件
  • 素材网站官网低价网站建设费用预算
  • 苏州网站设计kgwl个人网站有什么外国广告做
  • 浙江省网站建设报价简单网站开发工具
  • 物流网站的建设wordpress电视直播插件下载
  • 简述网站开发流程青岛做网站建设价格低
  • 网站开发的业务需求分析杭州推广公司
  • 网站建设技术实现难点app开发需要哪些软件
  • 响水建设局网站做网站需要会哪些知识
  • 企业制作企业网站个人网站可以做百度竞价
  • 做网站找投资人wordpress 5 主题教程
  • 做国外网站汇款用途是什么wordpress图片主题晨曦
  • 网站设计跟网站开发区别为什么网站需要维护
  • m 的手机网站怎么做网络推广方式和方法
  • wordpress图片自动轮播插件seo门户网站建设
  • 制作商业网站传奇网页游戏排名
  • 网站免费推广方案长沙房地产网站设计
  • 济南网站建设cnwenhui中交路桥建设网站
  • 韶关网站开发网站建设任务分解
  • 网站建设核心点阿根廷网站后缀
  • 哪些网站可以做招商广告语学校官网页面设计
  • 十堰城市建设网站网站开发流程宜春