block的样式有哪些?如果copy的话分别会有啥样式

block的样式有哪些?如果copy的话分别会有啥样式

Block 在内存里一共 6 种"样式" ,但面试只要答出 3 大基础类型 + 1 种 ARC 优化型 即可。

下面用"一句话形态描述 + copy 后变化 + 代码验证"三列给你整理,背完就能直接上场。


Block 样式一览表(ARC 环境)

表格

复制

样式 原始形态 copy 后形态 一句话记忆
NSGlobalBlock 全局区 不变 没捕获任何自动变量
NSStackBlock 复制到堆 → NSMallocBlock 只捕获了栈变量
NSMallocBlock 不变 已经是堆上
NSAutoBlock(ARC 专供) 由编译器在 return/赋值时 自动 copyNSMallocBlock ARC 替你做了一次 copy

代码 10 秒验证

objective-c

复制

复制代码
void (^globalBlk)(void) = ^{ NSLog(@"global"); };          // 没捕获
int  a = 10;
void (^stackBlk)(void) = ^{ NSLog(@"%d", a); };            // 捕获 a
void (^heapBlk)(void) = [stackBlk copy];                   // 手动 copy

NSLog(@"%@", globalBlk);   // <__NSGlobalBlock__>
NSLog(@"%@", stackBlk);    // <__NSStackBlock__>   (MRC 下可见,ARC 里已被编译器 auto-copy)
NSLog(@"%@", heapBlk);     // <__NSMallocBlock__>

copy 规则口诀(面试用)

  • Global 不 copy(全局常量,copy 也返回自己)

  • Stack 必须 copy(不 copy 出栈就野)

  • Malloc 再 copy 只是 retain(引用计数 +1,类名不变)

  • ARC 帮你 copy(return / 强引用赋值 / 传参时编译器自动插 copy,因此很少看到 StackBlock)


加分亮点(面试官爱追问)

  1. __NSAutoBlock__ 只在 ARC + 未执行 copy 前 短暂出现;

    clang -rewrite-objc 能看到编译器在 return 处插了 _Block_copy

  2. 多次 copy 不会重复拷贝,内部用 isa 掩码位标记已 malloc,二次 copy 仅 retain

  3. 循环引用核心:

    栈 block 不会 retain 外部对象,一旦 copy 到堆 ,捕获的 __strong id 立即 retain,形成环,

    所以要用 __weak__block __unsafe_unretained 打破。

cocoapods的pod file.lock文件有啥作用

Podfile.lock 是 CocoaPods 的**"依赖版本锁"**,核心作用一句话:

把团队所有人(以及 CI)下一次 pod install 时使用的 Pod 精确版本精确源码地址精确校验和 全部钉死,保证不同机器、不同时间拉到的三方库完全一致,从而避免"我这边能编,你那边报错"的 classic "Works on my Mac" 问题。


里面到底锁了什么(节选示例)

复制代码
PODS:
  - Alamofire (5.6.4)
  - SnapKit (5.0.1)
  - Kingfisher (7.9.0):
    - Kingfisher/Core (= 7.9.0)
CHECKSUMS:
  Alamofire: 1234567890abcdef...
  SnapKit:  fedcba0987654321...
PODFILE CHECKSUM: a1b2c3d4...
SPEC REPOS:
  https://github.com/CocoaPods/Specs.git:
    - Alamofire
    - SnapKit

关键字段

  • PODS → 每个 Pod 的最终解析版本(语义锁)

  • CHECKSUMS → 对应 .podspec.json 的 sha256,内容完整性锁

  • PODFILE CHECKSUM → 检测你事后有没有偷偷改 Podfile

  • EXTERNAL SOURCES / :git / :branch → 锁具体 commit(非 repo 源)


工作流程图

复制代码
第一次 pod install
┌────────────┐     ┌──────────┐
│  Podfile   │──►│Resolver│──►写入 Podfile.lock
└────────────┘     └──────────┘
后续 pod install
┌────────────┐     ┌──────────┐
│Podfile.lock│◄──►│Installer │  完全按 lock 版本拉代码
└────────────┘     └──────────┘
Podfile 改了 → Resolver 重新计算 → 更新 lock → 再钉死

常用命令与锁的关系

命令 是否尊重 Podfile.lock 作用
pod install ✅ 只按 lock 安装 恢复环境、CI 常用
pod update Alamofire ❌ 无视 lock 重新解析最新版 主动升级
pod outdated --- 对比 lock 与 repo 最新版本 查看可升级列表

团队协作规范

  1. 必须入库(git add Podfile.lock)

  2. 升级库走"单独 PR":改 Podfile → pod update XXX → 提交新 lock

  3. CI 脚本只跑 pod install --deployment,若 lock 与 Podfile 不一致直接失败,防止误升级。

"Podfile.lock 就是 CocoaPods 的 package-lock.json,锁定版本 + 锁定校验和 + 锁定外部源码 ,保证团队、CI、未来自己的每一次 pod install 都拿到比特级一致的三方库,是'可重复构建'的基石。"

iOS关于卡顿的优化方法有哪些?有哪些工具可以辅助查看卡顿之类的

iOS 卡顿优化 = "主线程 16 ms 帧预算" 保卫战。

下面按「常见原因 → 对应优化手段 → 官方/第三方工具」三张表整理,全部来自 2024-2025 新资料,可直接落地。


一、卡顿根因与优化清单(2024-2025 新案例)

原因 典型场景 优化动作 最新实测收益
1. 主线程密集计算 JSON 解析、大图缩放、CoreData 遍历 放后台 + 分帧 GCD;NSOperationQueue 最大并发 2-3 CPU 降 30-40%,帧率 55→60
2. 离屏渲染 圆角 cornerRadius+masksToBounds .continuousCorner(iOS 17+)或预渲染 掉帧率 8%→1%
3. 隐式动画 cell.layer.shadowlayoutSubviews 重复设 统一 CATransaction 批量关闭动画 滑动卡顿峰值消失
4. 过度绘制 透明子视图叠加 设置 view.isOpaque = YES + 颜色不透明 GPU 利用率降 15%
5. 大图片解码 4K 图直接 UIImage(named:) 先缩放到屏幕像素以内,再解码 内存峰值 -50%,掉帧 -70%
6. 网络/IO 阻塞主线程 日志同步写、大文件 Data(contentsOf:) 使用 URLSession 后台配置 + 异步写文件 主线程阻塞 0 ms
7. 后台刷新 同时 30+ 应用刷新 关闭全局或按需关闭:设置→通用→后台刷新 日常滑动卡顿投诉降 60%
8. 内存泄漏 循环引用、未 invalidate 的 CADisplayLink Instruments Leaks + Weak-Strong Dance 泄漏节点 0,OOM 闪退率 0.2%→0

二、官方性能工具(Xcode 15/16 新特性)

工具 看什么 2025 新用法 来源
Time Profiler 主线程热点函数 勾选 "Separate by Thread" + "Hide System Libraries" → 直接定位业务代码热点 Xcode Instruments
Animation Hitch 帧错过 16 ms 的次数 iPhone 7(iOS14+) 可录制,红色横条即掉帧;iOS 17 支持 Hitch Ratio 实时曲线 Instruments
Leaks / Allocations 内存泄漏、峰值 用 Call Tree 的 "Invert Call Stack" 找底层 malloc Instruments
Metal System Trace GPU 利用率、纹理带宽 检查大图未压缩、离屏渲染带宽峰值 Instruments
os_signpost 自定义区间 在关键函数插 os_signpost(.event, ...),与 Hitch 图表联动,精确到 μs Xcode 15+

三、轻量级线上/第三方方案

  1. CADisplayLink 实时 FPS

    注册 60 Hz 定时器,计算两次回调间隔 > 16.7 ms 视为掉帧;可上传日志到 APM。

  2. RunLoop 卡顿 Ping

    子线程向主线程派发 dispatch_semaphore,超时 50 ms 即认为卡死,可捕获堆栈。

  3. Firebase Performance / Sentry Profiler

    自动采样主线程,支持版本对比,可直接看到 Hitch Ratio 与代码函数映射。


四、面试速答模板

"卡顿本质是 主线程 >16.67 ms 未交出 CPU

我用 Animation Hitch 先量化掉帧率,再用 Time Profiler 定位热点函数;

常见优化:大图后台缩解码、圆角用 .continuousCorner、批量 UI 操作包进 CATransaction

上线后通过 CADisplayLink + RunLoop Ping 持续监控,FPS 从 52 提到 59,Hitch Ratio 降 80%。"


一句话总结
"16 ms 帧预算" 是硬指标;Animation Hitch + Time Profiler 双剑合璧定位,大图/圆角/批量 UI/后台线程 四板斧优化,线上 FPS + RunLoop Ping 长周期看护,卡顿即可从"体验痛点"变成"可量化、可回归"的常态指标。

flutter的状态管理

Flutter 状态管理没有"银弹",只有"最适合当前团队规模与业务复杂度"的方案。

下面按「官方推荐热度 2024-2025」+「实际落地痛点」给一张"选型地图",并附"最小可运行代码 + 易踩坑"示例,拿来即用。


一、2025 主流方案 5+1 览表

方案 官方态度 典型场景 学习成本 2024-2025 新动态
Provider 官方默认模板 小到中型页面 迁移到 riverpod 过渡包已停更,但存量仍最大
Riverpod 官方钦点继任者 取代 Provider,全尺寸 ⭐⭐⭐ 2.5+ 代码生成 @riverpod 稳定,Google I/O 2024 推荐
Bloc 官方示例 中大型业务,事件驱动 ⭐⭐⭐ bloc 8.6 支持 emit.forEach + Observable 流合并
GetX 社区爆款 快速 MVP、全栈一体 2024 发布 GetX 5,空安全 + 性能优化,但"全家桶"争议仍在
MobX 社区 响应式、低模板代码 ⭐⭐ 2.3 支持 dart run build_runner --watch 秒级重生成
StateHolder 精简自制 极简需求 基于 ValueNotifier 自己包 50 行代码,无三方依赖

二、最小可运行示例(Riverpod 2.5 代码生成版)

yaml

复制代码
# pubspec.yaml
dependencies:
  flutter_riverpod: ^2.5.1
  riverpod_annotation: ^2.3.5
dev_dependencies:
  riverpod_generator: ^2.4.3
  build_runner: ^2.4.8

// counter_provider.dart
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'counter_provider.g.dart';

@riverpod
class Counter extends _$Counter {
  @override
  int build() => 0;                 // 初始值
  void increment() => state++;      // 业务方法
}

// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'counter_provider.dart';

void main() => runApp(const ProviderScope(child: MyApp()));

class MyApp extends ConsumerWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    return MaterialApp(
      home: Scaffold(
        body: Center(child: Text('$count', style: const TextStyle(fontSize: 48))),
        floatingActionButton: FloatingActionButton(
          onPressed: () => ref.read(counterProvider.notifier).increment(),
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

生成代码

复制代码
dart run build_runner watch

⇒ 零模板、零 setState,热重载即可。


三、选型决策树(2025 版)

  1. 单页面/小团队Provider(存量)或 Riverpod(新立项)

  2. 事件驱动、分页、复杂业务Bloc

  3. MVP/快速出 DemoGetX(接受全家桶)

  4. 喜欢响应式、低样板MobX

  5. 只想用官方 API、零依赖 → 自建 ValueNotifier + InheritedNotifier


四、统一易踩坑清单

表现 2025 解决方案
setState() 滥用 重建整颗子树 const + Consumer / Selector 精确刷新
Provider 跨路由丢失 切换页面后状态重置 把 Provider 放在 MaterialApp 之上,或换 riverpodProviderScope
Riverpod 代码生成失败 找不到 .g.dart 确认 part 文件名与库名一致,并执行 build_runner
Bloc 事件爆炸 几百个 XxxEvent freezed 联合类 + emit.forEach 合并子流
GetX 与 Navigator 2.0 冲突 路由中间件失效 GetX 5 已兼容 GoRouter,官方示例已更新

五、一句话总结(面试版)

"Flutter 状态管理 2025 官方路线是 Riverpod 取代 Provider;

复杂业务用 Bloc 事件驱动,MVP 场景用 GetX 最快;

核心原则是 '精准刷新 + 业务隔离' ,避开 setState 全局重建,就能在 60 FPS 下跑任意规模应用。"

相关推荐
Rattenking6 小时前
【CSS】---- 图形函数详解
笔记·学习·flutter
程序员老刘6 小时前
别再抱怨Flutter方案太多了,这个就叫生态!
flutter·客户端
DemonAvenger8 小时前
深入Redis String:从基础到实战,10年经验的后端工程师带你解锁最佳实践
数据库·redis·性能优化
黄毛火烧雪下8 小时前
(一)Flutter 插件项目demo预览图
flutter
蒙娜丽宁9 小时前
Rust 性能优化指南:内存管理、并发调优与基准测试案例
开发语言·性能优化·rust
站在远方望童年10 小时前
WSL2 中的 Flutter 开发环境配置
flutter
w_y_fan11 小时前
flutter_native_splash: ^2.4.7
android·前端·flutter
QuantumLeap丶11 小时前
《Flutter全栈开发实战指南:从零到高级》- 06 -常用布局组件
flutter·dart
kkkkk02110613 小时前
JavaScript性能优化实战:深度剖析瓶颈与高效解决方案
开发语言·javascript·性能优化