首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在目标C中,如果我们将nil或null传递给@synchronized()块会发生什么?

在目标C中,如果我们将nil或null传递给@synchronized()块,不会发生任何异常或错误。@synchronized()块是用于实现线程同步的关键字,它会将括号内的对象作为锁来保护临界区的代码,以确保在同一时间只有一个线程可以访问该代码块。

当我们将nil或null传递给@synchronized()块时,实际上相当于没有提供任何对象作为锁。由于nil或null并不是一个有效的对象,所以不会有任何线程被阻塞或等待锁的释放。因此,对于传递了nil或null的@synchronized()块,它将不会起到任何线程同步的作用,多个线程可以同时访问临界区的代码。

需要注意的是,虽然不会发生异常或错误,但这样的使用方式是不推荐的。正确的做法是将一个有效的对象作为锁传递给@synchronized()块,以确保线程同步的正确性和可靠性。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C语言函数参数是如何传递的?

前言 我们可能听过C语言中的值和指针,在其他语言中,也有引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了。...为什么又有值,又有指针 看到这里,不知道你是否疑惑,为什么给函数传递参数的时候,一会是值,一会是指针呢?为什么指针就能改变参数的值呢?实际上,C语言里,参数传递都是值传递!...我们再通过图来理解前面为什么指针就可以交换a,b的值: 指针 从图中可以看出,虽然传递给函数的是指向a和b的指针的副本,但是它的副本同样也是指向a和b,因此虽然不能改变指针的指向,但是能改变参数a...我们还是利用前面所知来分析,由于传递给getMemory函数的参数都是一个副本,因此函数内的p也是外部p的一个副本,因此即便在函数内部,p指向了一新申请的内存,仍然不会改变外面p的值,即p还是指向NULL...c语言1232_副本_副本.jpg 可配合下面的图进行理解: 总结 本文总结如下: 函数的形参都是原数据的“副本”,因此函数内无法改变原数据 函数参数都是值,指针本质上也是如果想要改变入参内容

4.1K11

函数参数的值和指针有什么区别?

前言 我们可能听过C语言中的值和指针,在其他语言中,也有引用一说,那么他们到底有什么区别呢?如果你还不能准确地分辨,就该好好了解一下了。...调用swap前后 由于swap永远只是对a和b的副本进行操作,因此完全不影响原始的a和b的值。最终也不可能达到交换a和b的值的目的。 指针 那么为解决上面的问题,我们知道,需要指针。...为什么又有值,又有指针 看到这里,不知道你是否疑惑,为什么给函数传递参数的时候,一会是值,一会是指针呢?为什么指针就能改变参数的值呢?实际上,C语言里,参数传递都是值传递!...我们还是利用前面所知来分析,由于传递给getMemory函数的参数都是一个副本,因此函数内的p也是外部p的一个副本,因此即便在函数内部,p指向了一新申请的内存,仍然不会改变外面p的值,即p还是指向NULL...getMemory 总结 本文总结如下: 函数的参数都是原数据的“副本”,因此函数内无法改变原数据 函数参数都是值,指针本质上也是如果想要改变入参内容,则需要该入参的地址(指针和引用都是类似的作用

3K30
  • 借问变量何处存,牧童笑称用指针,Go lang1.18入门精炼教程,由白丁入鸿儒,go lang类型指针(Pointer)的使用EP05

    & 关键字可以从一个变量取到其内存地址。     * 关键字如果在赋值操作值的左边,指该指针指向的变量;* 关键字如果在赋值操作符的右边,指从一个指针变量取得变量值,又称指针的解引用。    ...nil概念上和其它语言的null、None、nilNULL一样,都指代零值空值。 一个指针变量通常缩写为 ptr: if(ptr !...与此同时,参过程,也可以使用指针: package main import ( "fmt" ) func change(val *int) { *val = 55 } func main(...结语     简而言之,很多编译型语言都在事实上存在指针,c/c++是真实的指针,而Java其实是指针的引用,可以理解为不能操作指针的值,不允许指针运算的指针。...,不存在引用传递,这样一来,必须有明确的指针类型,才可以保证值的前提下能对对象进行修改。

    45440

    iOS网络——NSURLSession详解及SDWebImage源码解析你要知道的NSURLSession都在这里

    这样看来它的使用真的很方便,并且默认自动开启多线程异步执行,上面栗子的回调输出了当前线程可以看出并不是主线程,所以回调如果要进行UI的更新操作需要放到主线程执行,相比使用NSURLConnection...>{name = 'MyDelegateQueue' 从输出结果看代理方法都是子线程执行,执行的队列也是我们创建的队列,如果需要在主线程执行代理发现就将代理队列设置为主队列即可。...valueForKey:key] mutableCopy]; //通过valueForKey方法如果字典没有对应key返回null所以需要删除为null的元素 [callbacks...,并将self传出去 什么线程发送通知,就会在什么线程接收通知 为了防止其他监听通知的对象回调方法修改UI,这里就需要在主线程中发送通知 */...接下来的一个比较重要的方法就是接收到图片数据的处理,接收到数据后就追加到可变数据如果需要在图片没有下载完成时就展示部分图片,需要进行一个解码的操作然后调用回调图片数据回,接着就会调用存储的进度回调来通知现在的下载进度

    2.9K100

    Thread 源码面试

    ,要么从对 run 方法的调用返回,要么抛出一个 run 方法之外传播的异常 每个线程都有名字,多个线程可能具有相同的名字,Thread 有的构造器如果没有指定名字,自动生成一个名字。...RUNNABLE 变成 TERMINATED 如果线程正好在等待获得 monitor lock 锁,比如在等待进入 synchronized 修饰的代码方法时,从 RUNNABLE 转至 BLOCKED...// name 我们可以自己如果默认是 "Thread-" + nextThreadNum(),nextThreadNum 方法返回的是自增的数字 // stackSize 可以设置堆栈的大小...,使线程的状态直接到 TERMINATED; 如果这个线程一个InterruptibleChannel的I/O操作中被阻塞,主动打断当前线程,那么这个通道将被关闭,线程的中断状态将被设置,线程收到一个...换句话说,如果要连续两次调用此方法,则第二个调用返回false(除非在第一个调用清除了其中断状态之后且第二个调用对其进行检查之前,当前线程再次被中断)。

    27600

    Thread的源码解析

    我们知道当创建Java对象时,系统总是先调用静态初始化 在上面的静态初始化调用了registerNatives()方法,并且使用了private来修饰,表面这个方法是私有的并不被外部调用。...Java中使用native关键字修饰的方法,说明此方法并不是由Java完成的,而是通过C/C++来完成的,并被编译成.dll,之后才由Java调用。...方法的具体实现是dll文件,当然对于不同平台实现的细节也有所不同,以上registerNatives()方法主要作用就是C/C++的方法映射到Java的native方法,实现方法命名的解耦...//没找到解释,字面意思是写入native的名称 private native void setNativeName(String name); 5、Thread的构造方法 //默认的什么都不...,当前线程处于阻塞状态(例如,进入一个同步方法或者同步代码,要先获得锁)   阻塞和等待的不同是,阻塞状态是等待一个排它锁               等待状态实在等待一个事件的发生,如等待时间到,

    61440

    多线程安全-iOS开发注意咯!!!

    之前我们介绍过时间片轮转算法,线程多种情况下退出自己的时间片。其中一种是用完了时间片的时间,被操作系统强制抢占。除此以外,当线程进行 I/O 操作,进入睡眠状态时,都会主动让出时间片。...如果临界区执行时间较长,比如是文件读写,这种忙等是毫无必要的 下面开始我们又爱又恨的锁 iOS锁 大家也可以参考这篇文章进行拓展:iOS锁 锁并是一种非强制机制,每一个现货出呢个访问数据资源之前视图获取...->多元的时候,我们的信号量由此诞生,多元信号量简称信号量 信号量的值减1 如果信号量的值小于0,则进入等待状态,否则继续执行。...sychronized的每个对象,Objective-C runtime都会为其分配一个递归锁并存储哈希表。...此时某个所有等待此条件变量的线程都会被唤醒并继续支持。 换句话说:使用条件变量可以让许多线程一起等待某个时间的发生,当某个时间发生时,所有的线程可以一起恢复执行!

    86920

    iOS开发进阶篇——FRP与ReactiveCocoa的介绍(一)

    如果a、b、c中一个或者多个变化(输入变化),y也要跟着变化。...通常我们等a、b、c变化结束后,再一起计算最终的结果y,a、b、c变化结束后并不会及时带来y的变化;如果我们a、b、c的变化和y提前做好映射(绑定),a、b、c任何一个变化y都能同时映射到对应的变化...在此基础之上,我们a、b、c的变化进行抽象封装,为什么要抽象封装呢?因为只有这样,我们才好统一进行管理,而这个抽象封装出来的东西,便构成了信号(Signal)。...举个简单的栗子:我们构造了三个输入框,产生a、b、c三个值,正常情况下,当a变化时,y随后发生变化,如图: 测试代码如下: @property (nonatomic, strong) UITextField...c发生变化时,进行下面的回调: - (void)onTextFieldChanged:(UITextField *)textField forEvent:(UIEvent *)event { if

    44590

    iOS开发进阶篇——FRP与ReactiveCocoa的介绍(一)

    如果a、b、c中一个或者多个变化(输入变化),y也要跟着变化。...通常我们等a、b、c变化结束后,再一起计算最终的结果y,a、b、c变化结束后并不会及时带来y的变化;如果我们a、b、c的变化和y提前做好映射(绑定),a、b、c任何一个变化y都能同时映射到对应的变化...在此基础之上,我们a、b、c的变化进行抽象封装,为什么要抽象封装呢?因为只有这样,我们才好统一进行管理,而这个抽象封装出来的东西,便构成了信号(Signal)。...举个简单的栗子:我们构造了三个输入框,产生a、b、c三个值,正常情况下,当a变化时,y随后发生变化,如图: 测试代码如下: @property (nonatomic, strong) UITextField...c发生变化时,进行下面的回调: - (void)onTextFieldChanged:(UITextField *)textField forEvent:(UIEvent *)event { if

    61580

    iOS开发进阶篇——FRP与ReactiveCocoa的介绍(一)

    如果a、b、c中一个或者多个变化(输入变化),y也要跟着变化。...通常我们等a、b、c变化结束后,再一起计算最终的结果y,a、b、c变化结束后并不会及时带来y的变化;如果我们a、b、c的变化和y提前做好映射(绑定),a、b、c任何一个变化y都能同时映射到对应的变化...在此基础之上,我们a、b、c的变化进行抽象封装,为什么要抽象封装呢?因为只有这样,我们才好统一进行管理,而这个抽象封装出来的东西,便构成了信号(Signal)。...举个简单的栗子:我们构造了三个输入框,产生a、b、c三个值,正常情况下,当a变化时,y随后发生变化,如图: 测试代码如下: @property (nonatomic, strong) UITextField...c发生变化时,进行下面的回调: - (void)onTextFieldChanged:(UITextField *)textField forEvent:(UIEvent *)event { if

    78901

    多线程安全-iOS开发注意咯!!!

    之前我们介绍过时间片轮转算法,线程多种情况下退出自己的时间片。其中一种是用完了时间片的时间,被操作系统强制抢占。除此以外,当线程进行 I/O 操作,进入睡眠状态时,都会主动让出时间片。...如果临界区执行时间较长,比如是文件读写,这种忙等是毫无必要的 下面开始我们又爱又恨的锁 三 iOS锁 锁并是一种非强制机制,每一个现货出呢个访问数据资源之前视图**获取(Acquire)锁,并在访问结束之后释放...->多元的时候,我们的信号量由此诞生,多元信号量简称信号量 信号量的值减1 如果信号量的值小于0,则进入等待状态,否则继续执行。...sychronized的每个对象,Objective-C runtime都会为其分配一个递归锁并存储哈希表。...此时某个所有等待此条件变量的线程都会被唤醒并继续支持。 换句话说:使用条件变量可以让许多线程一起等待某个时间的发生,当某个时间发生时,所有的线程可以一起恢复执行!

    41640

    双重检查锁定及单例模式

    本文余下的部分里,我们详细介绍双重检查锁定习语,从而理解它在何处失效。 单例创建习语 要理解双重检查锁定习语是从哪里起源的,就必须理解通用单例创建习语,如清单 1 的阐释: 清单 1....同步的代价不同的 JVM 间是不同的。早期,代价相当高。随着更高级的 JVM 的出现,同步的代价降低了,但出入 synchronized 方法仍然有性能损失。...B0 和 B5 处的前两行汇编代码 instance 引用从内存位置 049388C8 加载至 eax ,并进行 null 检查。...由于 inst 为 null,线程 1 //3 处进入第二个 synchronized 。...此行应该确保 instance 只为 null 引用一个构造完整的 Singleton 对象。该问题发生在理论和实际彼此背道而驰的情况下。 由于当前内存模型的定义,清单 7 的代码无效。

    1.8K30

    JUC并发知识_并行与并发

    ,并且将计数器置为 1;此时其它线程请求该锁,则必须等待;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器递增;当线程退出同步代码时,计数器递减,如果计数器为 0,则释放该锁。...(6)如果对一个变量执行lock操作,将会清空工作内存此变量的值,执行引擎使用这个变量前,需要重新执行loadassign操作初始化变量的值。...源代码—>编译器优化源代码–>指令并行也可能重排—>内存系统也重排 执行 一个变量被volatile修饰后,JVM会为我们做两件事: 每个volatile写操作前插入StoreStore...return v; } Java语言不像CC++那样可以直接访问底层操作系统,但是JVM为我们提供了一个后门,这个后门就是unsafe。unsafe为我们提供了硬件级别的原子操作。...new FairSync() : new NonfairSync();//参为true为公平锁 } 自旋锁 自旋锁(spinlock):是指当一个线程获取锁的时候,如果锁已经被其它线程获取

    28710

    【IOS开发基础系列】UIView专题

    讨论         这个值改变是因为设置了一些需要在动画中产生动画的属性。动画可以被嵌套。如果在没有动画调用那么setAnimation类方法什么都不做。...iOS,hit-Testing的作用就是找出这个触摸点下面的View是什么,HitTest检测这个点击的点是不是发生在这个View上,如果是的话,就会去遍历这个View的subviews,直到找到最小的能够处理事件的...调用super的目的就是为了把事件传递给nextResponder,并且如果我们touchesBegan没有调用super,则super不会响应其他的回掉(touchesMoved/touchesEnded...; }   6.1.6 坐标体系转换 // 像素point由point所在视图转换到目标视图view,返回目标视图view的像素值 - (CGPoint)convertPoint:(CGPoint...point fromView:(UIView*)view; // rect由rect所在视图转换到目标视图view,返回目标视图view的rect - (CGRect)convertRect:(

    59130

    Thread 源码面试

    ,要么从对 run 方法的调用返回,要么抛出一个 run 方法之外传播的异常 每个线程都有名字,多个线程可能具有相同的名字,Thread 有的构造器如果没有指定名字,自动生成一个名字。...当线程运行完成、被打断、被中止,状态都会从 RUNNABLE 变成 TERMINATED 如果线程正好在等待获得 monitor lock 锁,比如在等待进入 synchronized 修饰的代码方法时...我们来看下 run 方法的源码: 不会新起线程,target 是 Runnable 源码的 target 就是 new Thread 时,赋值的 Runnable。...// name 我们可以自己如果默认是 "Thread-" + nextThreadNum(),nextThreadNum 方法返回的是自增的数字 // stackSize 可以设置堆栈的大小...换句话说,如果要连续两次调用此方法,则第二个调用返回false(除非在第一个调用清除了其中断状态之后且第二个调用对其进行检查之前,当前线程再次被中断)。

    89651

    Java单例模式双重检查锁的问题

    本文余下的部分里,我们详细介绍双重检查锁定习语,从而理解它在何处失效。 要理解双重检查锁定习语是从哪里起源的,就必须理解通用单例创建习语,如清单 1 的阐释: 清单 1....同步的代价不同的 JVM 间是不同的。早期,代价相当高。随着更高级的 JVM 的出现,同步的代价降低了,但出入synchronized 方法仍然有性能损失。...注意:当第二个线程进入 synchronized 时,它并没有检查 instance 是否非 null。 双重检查锁定 为处理清单 3 的问题,我们需要对 instance 进行第二次检查。...B0 和 B5 处的前两行汇编代码 instance 引用从内存位置 049388C8 加载至 eax ,并进行 null 检查。...此行应该确保 instance 只为 null 引用一个构造完整的 Singleton 对象。该问题发生在理论和实际彼此背道而驰的情况下。 由于当前内存模型的定义,清单 7 的代码无效。

    1.8K20

    深入解析 Go Slice 底层实现

    Go ,与 C 数组变量隐式作为指针使用不同,Go 数组是值类型,赋值和函数参操作都会复制整个数组数据, 但slice不会复制值。...那这会导致什么问题呢? 假想每次参都用数组,那么每次数组都要被复制一遍。如果数组大小有 100万,64位机器上就需要花费大约 800W 字节,即 8MB 内存。这样消耗掉大量的内存。...由此我们可以得出结论: 把第一个大数组传递给函数消耗很多内存,采用切片(slice)的方式参可以避免复制值。切片是引用传递,所以它们不需要使用额外的内存并且比使用数组更有效率。...比如函数发生异常的时候,返回的切片就是 nil 切片。nil 切片的指针指向 nil。 空切片一般会用来表示一个空的集合。比如数据库查询,一条结果也没有查到,那么就可以返回一个空切片。...这之间究竟发生什么呢?

    84910
    领券