Apple提供了一些关于同步变量,甚至执行顺序的文档.我看不到有关cpu缓存行为的任何文档. Objective-C开发人员有什么保证和控制来确保线程之间的缓存一致性?

考虑下面的一个变量在后台线程上设置,但在主线程上读取:

self.count = 0;
dispatch_async(dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_HIGH,0),^ {
  self.count = 5;
  dispatch_async(dispatch_get_main_queue(),^{
    NSLog(@"%i",self.count);
  });
}

在这种情况下应该是不稳定的吗?

更新1

Inter-thread Communication中的文档保证共享变量可以用于线程间通信.

Another simple way to communicate information between two threads is to use a global variable,shared object,or shared block of memory.

在这种情况下,这是否不是必需的?这与Memory Barriers and Volatile Variables中的文档冲突:

If the variable is visible from another thread however,such an optimization might prevent the other thread from noticing any changes to it. Applying the volatile keyword to a variable forces the compiler to load that variable from memory each time it is used.

所以我仍然不知道是否需要volatile,因为编译器可以使用寄存器缓存优化,或者它不是必需的,因为编译器不知何故知道它是一个“共享”的东西.

文档不是很清楚共享变量是什么或编译器如何知道它.在上面的例子中,是否计算共享对象?假设count是一个int,那么它不是一个对象.它是一个共享的内存块,还是仅适用于__block声明的变量?对于非块,非对象,非全局共享变量,也许需要volatile.

更新2

大家认为这是一个关于同步的问题,不是.这是关于iOS平台上的cpu缓存行为.

解决方法

我知道你可能会问一下在线程中使用变量的一般情况(在这种情况下,关于使用volatile和锁的规则与ObjC相同,与普通C相同).但是,对于您发布的示例代码,规则有所不同. (我将跳过并简化事情,并使用Xcode来表示Xcode和编译器)
self.count = 0;
dispatch_async(dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_HIGH,self.count);
  });
}

我要假设self是一个NSObject子类,如下所示:

@interface MyClass : NSObject {
    NSInteger something;
}
@property (nonatomic,assign) NSInteger count;
@end

目标C是C的超集,如果你曾经做过任何ObjC的逆向工程,你会知道在编译之前,ObjC代码(不一样的)被转换成C代码.所有[self方法:object]调用被转换为objc_msgSend(self,“method:”,object)调用,self是一个带有ivars和其他运行时信息的C结构体.

这意味着这段代码并不完美.

-(void)doThing{
   NSInteger results = something + self.count;
}

只是访问某些东西不仅仅是访问变量,而是做自我>某事(这就是为什么在访问Objective C块中访问ivar时需要获得弱自身的参考,以避免保留循环).

第二点是Objective C属性并不存在. self.count变成[self count],self.count = 5变成[self setCount:5].目标C属性只是语法糖;方便的保存一些打字,使东西看起来更好一些.

如果您在几年以前一直使用Objective C,您将记得何时必须将@synthesize propertyName = _ivarName添加到您在标题中声明的ObjC属性的@implementation. (现在Xcode自动为您)

@synthesize是Xcode为您生成setter和getter方法的触发器. (如果你没有写@synthesize Xcode,希望你自己写setter和getter)

// Auto generated code you never see unless you reverse engineer the compiled binary
-(void)setCount:(NSInteger)count{
    _count = count;
}
-(NSInteger)count{
    return _count;
}

如果你担心线程问题与self.count,你担心2个线程一次调用这些方法(不直接直接访问相同的变量,因为self.count实际上是一个方法调用不是一个变量).

标题中的属性定义会更改生成的代码(除非您自己实现setter).

@property (nonatomic,retain)
[_count release];
[count retain];
_count = count;

@property (nonatomic,copy)
[_count release];
_count = [count copy];

@property (nonatomic,assign)
_count = count;

TLDR

如果你关心线程,并且要确保你不会通过在另一个线程上发生写入的方式读取值,然后将非原子变为原子(或者摆脱非原子,因为原子是默认的).这将导致代码生成这样的东西.

@property (atomic,assign) NSInteger count;

// setter
@synchronized(self) {
    _count = count;
}

这不能保证你的代码是线程安全的,但是(只要你只访问属性视图它是setter和getter)应该意味着你避免在另一个线程上写入时读取值的可能性.更多关于原子和非动态的信息在this question的答案.

ios – Objective-C cpu缓存行为的更多相关文章

  1. 详解使用双缓存解决Canvas clearRect引起的闪屏问题

    这篇文章主要介绍了详解使用双缓存解决Canvas clearRect引起的闪屏问题的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. HTML5 Web缓存和运用程序缓存(cookie,session)

    这篇文章主要介绍了HTML5 Web缓存和运用程序缓存(cookie,session),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. 详解前端HTML5几种存储方式的总结

    本篇文章主要介绍了前端HTML5几种存储方式的总结 ,主要包括本地存储localstorage,本地存储sessionstorage,离线缓存(application cache),Web SQL,IndexedDB。有兴趣的可以了解一下。

  5. ios – 异常断点处于活动状态时,应用程序在启动时崩溃

    我刚开始继续开发一款适用于商店的传统iPad应用程序.我注意到项目中的异常断点未启用.当我启用它时,应用程序在启动时崩溃,但在输出窗口中没有给出任何信息,而在线程视图中只有相当无用的信息(见下文)我试着解决它..>将Autolayout设置为关闭.>通过编辑和重新保存故事板文件..但到目前为止没有运气.我的猜测是,故事板中的某些内容被破坏了,因为AppDelegates“确实完成了启动……”

  6. ios – Swift 4添加手势:覆盖vs @objc

    我想在我的视图中添加一个手势,如下所示:但是,在Swift4中,我的编译器给出了以下错误:建议添加@objc以将此实例方法公开给Objective-C.实现此目的的另一个选项将覆盖touchesBegan()函数并使用它来处理点击.我试图以“Swift”的方式做到这一点,而不必带入Obj-C.有没有纯粹的Swift方式来添加这个轻击手势而不使用@objc?

  7. ios – Objective-C中“and”关键字的含义是什么?

    我在Xcode中输入了一条评论,但忘了领先//.我注意到了这一点并且突出显示为关键字.我做了一些谷歌搜索,但我似乎无法弄清楚它做了什么.这是什么意思?解决方法它是&&的同义词.见iso646.h.

  8. ios – 以编程方式在Swift中添加联系人

    我想在Swift中以编程方式添加联系人.我发现了一些Objective-C示例,但我没有让它们工作,甚至在Objective-C中也没有.我不希望这涉及到AddressBookUI,因为我想从我自己的UI中获取值.解决方法这是在Swift中添加联系人的快速方法.我在我的iPhone5iOS7.1上验证了它,因为我发现模拟器并不总是与我的手机对AB的东西相同.您可以添加一个按钮并指向此方法:顺便说一下–它假设你已经分配了一个地址簿var,你可以通过覆盖viewDidAppear来打开视图.它也会执行安全提示

  9. ios – 如何从变量访问属性或方法?

    是否可以使用变量作为Swift中方法或属性的名称来访问方法或属性?在PHP中,您可以使用$object->{$variable}.例如编辑:这是我正在使用的实际代码:解决方法你可以做到,但不能使用“纯粹的”Swift.Swift的重点是防止这种危险的动态属性访问.你必须使用Cocoa的Key-ValueCoding功能:非常方便,它完全穿过你要穿过的字符串到属性名称的桥,但要注意:这里是龙.

  10. iOS:核心图像和多线程应用程序

    我试图以最有效的方式运行一些核心图像过滤器.试图避免内存警告和崩溃,这是我在渲染大图像时得到的.我正在看Apple的核心图像编程指南.关于多线程,它说:“每个线程必须创建自己的CIFilter对象.否则,你的应用程序可能会出现意外行为.”这是什么意思?我实际上是试图在后台线程上运行我的过滤器,所以我可以在主线程上运行HUD(见下文).这在coreImage的上下文中是否有意义?

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部