block深入浅出

typedef void (^Callback)(id result);
- (void)viewDidLoad {
[self callbackDosomething:^(id result) {
NSLog(@"%@",result);
}];

}

- (void)callbackDosomething:(Callback)callback{
callback = [self callbackReDosomething:callback];
}

- (Callback)callbackReDosomething:(Callback)callback{
if (callback) {
callback(@"dosomething");
}
return callback;
}
此处的callback就是用来传递的,在另一个方法里面才callback回调

block是OC对闭包实现的一个对象,为什么说block是对象了,因为在block的数据结构中存在isa指针

1、block分为三种:NSConcreteGlobalBlock、NSConcreteStackBlock、NSConcreteMallocBlock。

第一种block是全局block,如果一个block没有引入外部变量,那么这个block就是全局block,全局block在编译时期就已经确定大小了,如同宏一样;
第二种block是栈block,当引入了外部变量时,这种block就是栈block了,NSConcreteStackBlock内部会有一个结构体__main_block_impl_0,这个结构体会保存外部变量,使其体积变大。而这就导致了NSConcreteStackBlock并不像宏一样,而是一个动态的对象。而它由于没有被持有,所以在它的内部,它也不会持有其外部引用的对象。(注意,栈block是不会持有外部变量的)
第三种block是堆block,堆block就是一个block被copy到堆上,堆block会持有外部引用对象,所以会导致可能的对象延迟释放,或者循环引用的问题。(在MRC下,局部变量如果没有用_block,在block中会对其进行copy操作,而用了_block则只会引用其地址,这也就是为什么改变局部变量需要用_block修饰了)

注意:在MRC和ARC下block的区别
将block作为实例的属性变量时,MRC下需要手动copy到堆中,也就是栈block–>堆block(如果不copy就是栈block,栈block不会持有对象),而在ARC中属性赋值默认是strong,到了block自然就变成了copy,所以在ARC下默认是堆block。

block 的生命周期:
(特别注意:堆block会持有对象,这样就导致,如果堆block不释放的话,其持有的对象也不会释放,这样就会导致循环引用或者延迟释放,所以一般的做法是_weak(ARC)或_block(MRC))

宏:
·#define weak(obj) __weak typeof(obj) weak##obj = obj

<think> 嗯,用户这次想深入浅出地了解SCSI子系统的知识,还特别提到要"深入且易懂"。看来用户可能是嵌入式开发人员,或者正在学习存储相关技术,因为之前引用的资料提到嵌入式Linux和硬件操作。用户特意强调不要被引用内容干扰,说明ta需要的是针对性强的专业讲解。 从技术角度看,SCSI子系统确实是个多层次复合体。我计划从最基础的物理层开始讲起,这样能照顾到不同背景的读者。用户提到"深入浅出",意味着需要平衡专业性和可读性,避免直接堆砌术语。考虑到SCSI协议有新旧版本差异,应该先明确核心架构再补充扩展内容。 用户引用的资料虽然提到低级格式化和设备连接,但SCSI体系远不止这些。需要覆盖协议栈全貌:从SCSI-3标准模型分层,到Linux内核中的驱动实现结构。特别要解释清楚SCSI中间层的作用,这是很多人容易混淆的点。存储栈示意图和伪代码示例会是很好的辅助材料。 注意到用户上次询问时引用了嵌入式书籍推荐,可能对实践应用更感兴趣。所以除了理论讲解,应该补充驱动开发实例和性能调优参考。最后推荐资源时优先选择带图解的教程,比如《存储技术原理分析》那本,正好符合用户"深入浅出"的需求。 需要警惕几个易错点:一是区分SCSI协议和SAS/SATA物理接口的关系;二是澄清SCSI命令在NVMe等新协议中的演变;三是避免过早引入多路径管理等高级话题。先建立基础认知框架更重要。 </think> 以下是SCSI子系统的深入浅出讲解,结合架构原理Linux实现,帮助您系统理解: --- ### **一、SCSI子系统核心架构** SCSI协议采用**分层模型**(参考SCSI-3标准): ``` $$ \begin{array}{c} \text{应用层} \\ \downarrow \\ \text{SCSI\textbf{中间层}(命令转换)} \\ \downarrow \\ \text{HBA驱动层(适配硬件)} \\ \downarrow \\ \text{物理设备(磁盘/磁带等)} \end{array} $$ ``` 1. **SCSI命令集** - 所有操作通过**CDB(Command Descriptor Block)** 实现,例如读命令:`$ \text{CDB[0]=0x28, CDB[1-5]=LBA, CDB[6-9]=长度} $` - 支持 **$ > 16TB $** 大容量设备(使用16字节CDB) 2. **Linux内核中的实现** ```c // 驱动注册示例 (drivers/scsi/scsi_scan.c) struct scsi_device *sdev = scsi_alloc_sdev(host, channel, id); scsi_probe_and_add_lun(host, channel, id, 0, NULL); ``` - **核心组件**: - **sd_mod**:SCSI磁盘驱动 - **sg**:通用SCSI命令直通接口 - **scsi_transport**:总线管理框架 --- ### **二、关键模块详解** #### ▶ **SCSI中间层** 1. **命令转换** 将块设备请求转为SCSI CDB: ``` 通用块层I/O请求 → SCSI命令队列 → HBA驱动 ``` 2. **错误处理** - 自动重试机制(如`$ \text{CHECK\_CONDITION} $`状态) - 超时控制(默认30秒) #### ▶ **HBA驱动层** ```c // 适配器驱动模板 (include/scsi/scsi_host.h) struct scsi_host_template { const char *name; int (*detect)(struct scsi_host_template *); int (*queuecommand)(struct Scsi_Host *, struct scsi_cmnd *); void (*eh_strategy_handler)(struct Scsi_Host *); }; ``` - 负责DMA内存映射 - 中断处理队列调度 #### ▶ **设备发现流程** ```mermaid graph LR A[扫描SCSI总线] --> B[发送INQUIRY命令] B --> C{设备响应?} C -->|是| D[分配scsi_device] C -->|否| E[跳过该LUN] D --> F[创建设备文件/dev/sdX] ``` --- ### **三、Linux中的调试工具** 1. **内核日志追踪** ```bash dmesg | grep -i scsi # 查看设备初始化日志 ``` 2. **SCSI命令直通测试** ```bash sg_raw /dev/sda 08 00 00 00 01 00 # 发送READ(6)命令 ``` 3. **性能分析** ```bash iostat -x 1 | grep sda # 监控I/O延迟 ``` --- ### **四、推荐学习资料** 1. **书籍** - 《Linux设备驱动程序》Chapter 16: SCSI子系统 - 《存储技术原理分析》第5章:SCSI协议深度解析 2. **在线资源** - Linux内核文档:`Documentation/scsi/`(含核心API说明)[^1] - SCSI标准协议:**T10官网**(公开SPC-5/SBC-4文档)[^2] 3. **实践项目** - 使用**QEMU模拟SCSI设备**: ```bash qemu-system-x86_64 -drive file=disk.img,format=raw,if=scsi ``` - 编写简易SCSI伪驱动(示例代码见GitHub内核demo)[^3] --- ### **相关问题** 1. SCSINVMe协议在Linux内核中的实现差异是什么? 2. 如何编写一个SCSI HBA驱动? 3. SCSI多路径(multipath)是如何保证存储高可用的? > 提示:学习时建议结合`strace`跟踪系统调用和`perf`分析SCSI命令链路延迟[^1][^3]。 [^1]: Linux SCSI子系统文档 [^2]: T10技术委员会协议标准 [^3]: QEMU SCSI设备模拟教程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值