在objective c atomic-c中atomic和nonatomic有什么区别?retain有什么用

用户名:xiesiyuana
文章数:216
访问量:7826
注册日期:
阅读量:1297
阅读量:3317
阅读量:447391
阅读量:1132616
51CTO推荐博文
nonatomic:非原子性访问,不加同步,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问。&&&&&&&&&&&&&&&&&&& (atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所 以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。)assign:&简单赋值,不更改索引计数&&&&&&&&&&&&&&&对基础数据类型 (NSInteger)和C数据类型(int,&float,&double,&char, 等),否则可能导致内存泄露。例如当使用malloc分配了一块内存,并把它的地址赋值给了指针a,后来如果希望指针b也共享这块内存,于是讲a赋值给(assgin)b。这时就用到了assgin,此时a和b指向同一块内存。但是现在问题出现了,当a不再需要这块内存时,能都直接释放呢?肯定是不能的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候引起程序crash掉。copy:建立一个索引计数为1的对象,然后释放旧对象&&&&&&&&&&& &&对NSString&retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1&&&&&&&&&&&&&对其他NSObject和其子类copy与retain的区别:copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。eg:&& 一个NSString&对象,地址为0×1111&,内容为@”STR”&Copy&到另外一个NSString&之后,地址为0×2222&,内容相同,新的对象retain为1&,旧有对象没有变化retain&到另外一个NSString&之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1也就是说,retain&是指针拷贝,copy&是内容拷贝。
了这篇文章
类别:未分类┆阅读(0)┆评论(0)2127人阅读
笔试面试(59)
【atomic/nonatomic】(1)atomic[默认属性]:OC使用的一种线程保护技术,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。(2)nonatomic:非原子性访问,属性赋值的时候不加锁,多线程并发访问会提高性能。但可能会造成不安全。如果不加该属性,则默认setter/getter两个方法都是原子性事务访问。所以,atomic和nonatomic用来决定编译器生成的getter,setter是否为原子操作。【assign/copy/retain】(1)assign[默认值]:新建一个指向对象的指针(引用),但是不更改对象的引用计数,不考虑内存管理;常常用于基础数据类型(NSInteger)和C语言数据类型(int ,float,double,char等)。(2)copy:建立一个引用计数为1的对象,原有对象不做改变;常常用于NSString。在赋值时传入值的一份拷贝,拷贝工作由copy方法执行。(3)retain:&& 释放旧的对象,将旧对象的值赋给输入对象,再把输入对象的引用计数+1.& ;常常用于NSObject和其子类。需要对变量release,再retain新值。指定retain会在赋值时唤醒传入值的retain消息,此属性只能用于OC对象类型,而不能用于Core Foundation(retain会增加对象的引用计数,而基本数据类型或者Foundation对象都没有引用计数的概念)。小结:assign和retain的区别,就是使用引用计数,可以对一个内存的释放方便很多。copy就是把原来的内存复制一遍,使各自都拥有一个内存,这样释放的时候也不会出错。【copy和retain的区别】copy是创建一个新对象。retain是创建一个指针,引用计数+1.如:一个NSString对象,内存地址为:0x1111,内容为@“Hello”。(1)copy到另外一个NSString后,地址为0x2222,内容相同(新建一个内容,内容拷贝),新的对象引用计数为1,旧的对象没有改变。(2)retain到另外一个NSString后,地址相同(新建一个指针,指针拷贝),内容相同,对象的引用计数+1.【assign和retain的区别】(1)接触过C,那么假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的。因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉。(2)知道了上述assign的问题,那么如何解决呢?最简单的一个方法就是使用引用计数。我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时,引用计数增加到2.这时如果a不再使用这块内存,他只需要引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数-1.当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。小结:assign就是直接赋值,从而可能引起1中的问题,当数据为int,float等原生类型时,可以使用assign。retain使用了引用计数,retain引起引用计数+1,release引起引用计数-1.当引用计数为0时,dealloc函数被调用,内存被回收。【strong和weak】(1)strong[默认值]:表明这是一个强引用。相当于retain属性。只要引用存在,对象就不能被销毁。当所有强引用消除时,对象才能被释放。(2)weak:弱引用。相当于assign属性。一般为了避免retain cycles(就是父类中含有子类,父类retain了子类;子类中又调用了父类,子类又retain了父类),导致无法release,才会使用weak。小结:strong和weak只有你在使用ARC的时候才能使用,此时你是不能使用retain,release,autorelease这些方法的,因为ARC会在必要的地方自动插入这些语句。所以我们需要在对象属性加上strong或者weak。【readonly和readwrite】这两个修饰很明显,readonly表示这个属性是只读不可修改的,readwrite(默认)表示属性是可读可写的。为了对某一个属性有较好的封装性,我们对同一个属性在.h文件中设置成readonly、在.m文件中设置成readwrite.如下所示:头文件中:#import &UIKit/UIKit.h&
@interface ViewController : UIViewController
@property(nonatomic,copy,readonly) NSString *
@end实现文件:#import &ViewController.h&
@interface ViewController ()
@property(nonatomic,copy,readwrite) NSString *
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
@end这样我们就对同一个属性设置了较好的封装性。& & & &总结下,对于一个属性的4个默认的属性修饰是:atomic,readwrite,assign,strong。github主页:& 。欢迎大家访问!
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1686779次
积分:23393
积分:23393
排名:第283名
原创:623篇
转载:36篇
评论:476条
文章:19篇
阅读:56926
文章:19篇
阅读:35481
文章:11篇
阅读:15743
阅读:41200
文章:60篇
阅读:113861
文章:79篇
阅读:187545
文章:220篇
阅读:683135
文章:51篇
阅读:174133
Android应用:
Github主页:
(1)(7)(10)(7)(5)(4)(7)(7)(5)(15)(4)(8)(10)(4)(24)(29)(10)(22)(33)(106)(130)(79)(132)在objective-c中atomic和nonatomic有什么区别?retain有什么用?_问答_ThinkSAAS
在objective-c中atomic和nonatomic有什么区别?retain有什么用?
在objective-c中atomic和nonatomic有什么区别?retain有什么用?
比如下面的代码@property(nonatomic, retain) UITextField *userN
@property(atomic, retain) UITextField *userN他们有啥区别,retain在这里起啥作用
debug后记得stop,就不会总出现这样的问题了,也就不用每次都重启啦~!
我一般我会出现这种情况是因为我在模拟器上还在运行的时候,直接把应用程序删除,几次中必会出现上面的情况,然后就悲剧了。一般来说debug完了,手动停止运行很少会出现上面的情况。
xcode4.3.2目前没出现过,尝试一下新版的?
重启一般都能解决
我都是重启Xcode和模拟器
我遇到的情况:
1,不需要重启,点停止运行按钮后,隔几秒在运行程序就不会报这个错了。但如果中间隔的时间太短就会出现。
2,我用的是黑苹果,以前用Xcode4.3的时候也没遇到这个问题,升到4.6后经常遇到这个问题。不知道是黑苹果的问题还是Xcode新版本的问题。
如果是手机调试,重启手机就ok了
CAKeyframeAnimation 指定动画路径
正确的写法是
__unsafe_unretained id&EGORefreshTableHeaderDelegate& _
@property(nonatomic,assign) id &EGORefreshTableHeaderDelegate&
crash和此处无关,是你别的地方已经释放了此对象。如果此处改为强引用,则不可避免的造成retain cycle从而内存泄露,是万万不能的。你要做的是检查为何释放后还会被回调。
开启ARC后,如果部署iOS版本是5.0以上,请使用weak,5.0以下的才用unsafe_unretained,楼上说的设置成strong是不对的
~~Note: In addition, in OS X v10.7, you cannot create weak references to~~
~~instances of NSFontManager, NSFontPanel, NSImage, NSTableCellView,~~
~~NSViewController, NSWindow, and NSWindowController. In addition, in OS~~
~~X v10.7 no classes in the AV Foundation framework support weak~~
~~references.~~
~~For declared properties, you should use as for~~
~~variables you should use __unsafe_unretained instead of __weak.~~
ARC is supported in Xcode 4.2 for OS X v10.6 and v10.7 (64-bit applications) and for iOS 4 and iOS 5. Weak references are not supported in OS X v10.6 and iOS 4.
~~考虑到delegate的类型不确定性与非拥有性,毫无疑问:~~
~~weak是不能使用的~~
~~strong是绝对错误的~~
~~assign是没有问题的~~
~~unsafe_unretained是表意清晰的~~
由于delegate的非拥有性,在ARC下应该首选weak,因为它可以防止野指针问题,更加安全。
但如果在iOS4下,由于还未支持weak,就只能退而求其次,使用unsafe_unretained了。
开启ARC后,不需要设置成unsafe_unretained,设置成strong即可
怀疑是[self presentModalViewController:_avatarPicker animated:YES];这个时候 _avatarPicker 没了
建议这样做- (id)init
_avatar = [[UIButton alloc] initWithFrame:avatarRect];
[_avatar setBackgroundColor:[UIColor blackColor]];
[_avatar addTarget:self action:@selector(pickAvatar:) forControlEvents:UIControlEventAllTouchEvents];
[[self view] addSubview:_avatar];
- (void)pickAvatar:(id)sender
if (nil == _avatarPicker) {
_avatarPicker = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
[_avatarPicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[_avatarPicker setMediaTypes:[UIImagePickerController availableMediaTypesForSourceType:[_avatarPicker sourceType]]];
[_avatarPicker setDelegate:self];
[_avatarPicker setAllowsEditing:YES];
[self presentModalViewController:_avatarPicker animated:YES];
作为一个半路转学ios开发的开发者,从我两个月的开发经历来看,objective-c一点也不难。我的开发的程序经历了如下的变迁,我也趁机来总结下得失最弱智的hello world从xcode新建一个project,然后打开窗口编辑器(Interface Builder,简称IB),拖入一个UILabel组件,写上"Hello World",这样就算完了。了解代码的组成虽然它的名字叫"objective-c",但似乎一点也不同于我以前写过的c语言,里面充满了无数让菜鸟迷惑的潜规则。为什么用#import而不用#include?@property是什么东西?它括号里面的(strong, nonatomic)又会?为什么我在@interface里声明了属性,还要再@property?它和@synthesize又有什么关系?这一阶段基本上集中了很多小白的问题,幸运的是这些问题都很容易在网上找到答案,而且如果你有其它的语言基础的话也会很容易理解这些语法。我在这一阶段写出的代码基本惨不忍睹,所有的代码都放在一个controller里,一个是因为我懒,另一个是因为我还没有掌握objective-c开发世界里的编码风格,所以索性就不要风格了。你的代码里可能充满了IBOutlet或者IBAction。不过只要你的代码能够工作,那么一切都是值得的。初窥精髓在cocoa框架里的一大精髓就是delegate,中文翻译为"委托"模式(本人自创直译其为"代理"模式)。虽然这一模式并不是cocoa的独创,但也是它运用的最好的地方之一。delegate模式解决了controller和view之间的交互问题。在我写代码的时候,往往发现只要seDelegate,就会发生很多很美妙的事情。另外你会发现,ios提过的这些基本组件已经无法满足你对交互的要求了,这时候你可能需要开始扩展它的一些基本组件。扩展它的基本组件是件很简单的事情,sdk中也预留了很多接口供我们override。一般这时候的你看着以前自己写的丑陋的代码,会忍不住开始重构它,放手去重构吧。得心应手其实了解了objective-c世界的一些潜规则以后,除了对它API的掌握,它就基本已经成为一种普通的工具语言了。但要注意的是,xcode 4以后引入了ARC,也就是自动引用计数这个玩意,并且它默认是打开的。可能会给你造成一些困扰。很多初学者会担心交由系统管理内存会造成内存的浪费,其实了解它的原理后,发现它的实现非常简单,其实就是当一个对象的没有人引用时,系统就自动把它release掉。而交给系统来处理也可以避免内存碎片的形成,但如果你需要频繁在一块内存区域读写内存,比如自己实现的消息队列之类的,建议自己通过struct来实现。但是如果你定义这样一个structtypedef struct _Test {
NSString *
} T编译器会无情的告诉你,在struct里无法引用objective-c的对象,为什么?因为ARC无法控制到struct里的引用计数。但是如果你非要在struct里引用一个对象怎么办,你可以使用void *来保存一个指针typedef struct _Test {
void *nameP
// malloc的指针也不会被arc, 注意自己释放
Test test = (Test *)malloc(sizeof(Test));
test.namePtr = (__bridge void *)[NSString stringWithString:@"Hello"];但有一个问题,在上面的代码中[NSString stringWithString:@"Hello"]这只是个临时变量,虽然它被struct的指针指向了,但是前面说到了,这不会引起ARC的引用计数。那么就是说ARC会认为没有人引用这个变量,如果不出意外,这段代码执行玩以后,这片内存会被系统回收。如果你再次调用这个指针指向的内存,只会得到一个EXC_BAD_ACCESS错误。解决方法其实很简单,我们可以强制让ARC计数,比如在当前的@interface里设置一个变量指向这个string,这样它就不会被释放了@interface TestObj : NSObject {
NSString *
- (void)initName
name = [NSString stringWithString:@"Hello"]; // 强制引用
Test test = (Test *)malloc(sizeof(Test));
test.namePtr = (__bridge void *)
}OK, 说了这么多比较乱,最后还吐槽了下ARC。最后的结论就是上手是很快的,但学好也需要自己钻研。
第一层:objective-c语法 三天即可修炼成功
第二层:民工UI:UIView、UILabel、UIImageView、UITableView、UINavigationController、UITabBarViewController的用法。视资质要一个月到两个月时间修炼。
第三层:各功能API:网络请求、持久化、通讯录、GPS、邮件API、各种API。半年
第四层:UI进阶:旋转屏幕、核心动画、自定义描绘视图、绘图上下文等。半年
第五层:高级技能:运行时、cocos、OpenGLES等。目前尚未修炼完成,尚不知所需日期。
建议1,不系统学习
建议2,从写Hello World开始,一个一个app的写,用到什么学什么
建议3,市面上没有一本书是靠谱的
建议4,看官方文档和sample code
先解释一下TableView的布局,一个TableView的内容两级,Section和Section中的Row,每个Row对应的视图成为TableViewCell。拿 设置.app 举例,如下图:
图中有两个Section
Section 0 中有6个Row -- 飞行模式~运营商
Section 1 中能看到3个Row -- 声音~桌面再说问题里的两个方法。- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexP这个方法返回的就是某个cell,可以自定义各种样式渲染,也可以用几种默认样式去渲染。
indexPath标示的是你要渲染的这个cell的位置,indexPath对象里有两个属性,section和row,顾名思义,可以定位某个cell。
注意:这个方法会在某个cell出现在屏幕中的时候被调用,而且是没出现一次就被调用一次。因为一个cell对象在屏幕可见区域消失的时候被回收,给其他出现在可见区域的cell复用。所以,在这个方法里渲染某个cell的时候,最好用个for循环或者什么的把cell清理干净。- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section这个方法,是在TableView生成的时候被调用(或者对tableView对象调用reloadData时),返回某个section中的row(cell)数量。
例如,在 设置.app 的界面里,应该是switch (seciton) {
1、NSIndexPath主要包含(NSUInteger)section和(NSUInteger)row,每个row必然是属于一个section的,否则这个row没有意义,- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section里面就是表明各section有多少row。
2、打开Contacts,里面的那些A、B、C...这样的标题就属于section header,header + rows + footer就构成了一个完整的section. 可以通过- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)进行定制header,footer类似
先说release,不是直接释放内存,是引用计数-1,而当引用计数0的时候,sdk会gc掉这段内存。应用的main函数里可以看到,有初始化一个AutoRealesePool,就是干这个。
另外,每个对象都有autorelease方法,对他调用一把autorelease后,就不用手动release了。
再看示例代码,这个要看你 ClassB 里 property 的定义:
(copy) ClassB * b,那么setProperty的时候内存里会复制一个a,付给b。则(a-& mema[rc=1], b-&memb[rc=1])
(retain) ClassB * b,就给a的引用计数+1,b还是指向这段内存。则(a-& mema[rc=2] &-b)
所以,setProperty以后,对a调用release的时候,就是把a指向的内存段的rc-1。copy的情况下,a已经不可以调用了,掉了就会BAD_ACCESS,retain的情况下,a还可以调用,因为他的rc=2-1=1。
再说llvm3里抛弃这个的问题,llvm3有个特性,叫ARC,就是AutoReferenceCount,rc被自动管理了。在ARC打开的文件中,release autorelease retain 都是不允许使用的。在XCode的编译规则中可以加参数选择是否使用ARC编译某个文件。
后ARC时代,要注意属性是函数局部的,还是类全局的这些,因为,开发者已经不需要手动回收内存,ARC会依据他的可见性,或者是生命周期去处理。在使用完某个对象后,要 =nil一下,ARC会马上干掉他。
最后,在前ARC时代几个简单的规则:
使用alloc创建的实例引用计 rc=1
作为addObject:等方法的参数 rc+=1
作为removeObject:等方法的参数 rc-=1
调用removeFromeOOXX方法 rc-=1
调用 retain rc+=1
调用 copy 复制一份 rc不变
调用 release rc-=1
---- 使用建议 ----
使用alloc创建后,一定要使用release释放,或调用autorelease交给系统管理
add以后,一定记得remove
通常 为了不BAD_ACCESS 我在dealloc 里都是 self.property =
虽然不知道原因,但是经尝试,在做图片的时候把背景图层的颜色去掉能解决问题(尽管这个图层在导出时我们根本就没让它显示出来)。我是在改一个mac app的图标的时候发现这个问题的,见图:
改好以后从dock上移除一下图标就Ok了,dock会对图标文件缓存
UIButton *btn = [[UIButton alloc] initWithFrame:
CGRectMake(0, 0,
btnImage.size.width,
btnImage.size.height)];
[btn setImage:faceImage forState:UIControlStateNormal];Frame在最开始的时候弄进去,不要后来设置bounds
retain是给属性的引用计数加1
这里的retain是指,这个setter会给参数的引用计数加1。例如:self.userName = uN这个时候 uName的引用计数会被加1。
但是SDK5.0以后支持ARC,就是自动应用计数,所以定义属性就不用retain和copy了,而用strong,让ARC来管理。
提供苹果核的一篇文章可供参考:
atomic线程安全,性能低于nonatomic。noatomic不保证线程安全。
atomic 并不代表线程安全,只是说对同一对象的set和get的操作是顺序执行的。
添加你想要问的问题
PHP开发框架
开发工具/编程工具
服务器环境Objective-C 属性特性(assign , retain , copy , readonly , readwrite , atomic , nonatomic)?
Objective-C 属性特性(assign , retain , copy , readonly , readwrite , atomic , nonatomic)?
assign:指定setter方法用简单的赋值,这是默认操作。你可以对标量类型(如int)使用这个属性。你可以想象一个float,它不是一个对象,所以它不能retain、copy。
assign:简单赋值,不更改索引计数(Reference Counting).使用assign: 对基础数据类型 (NSInteger)和C数据类型(int, float, double, char,等)
retain:指定retain应该在后面的对象上调用,前一个值发送一条release消息。你可以想象一个NSString实例,它是一个对象,而且你可能想要retain它。
retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 ,使用retain: 对其他NSObject和其子类 ,retain,是说明该属性在赋值的时候,先release之前的值,然后再赋新值给属性,引用再加1。
copy:指定应该使用对象的副本(深度复制),前一个值发送一条release消息。基本上像retain,但是没有增加引用计数,是分配一块新的内存来放置它。copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。
copy:建立一个索引计数为1的对象,然后释放旧对象,copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。
readonly:将只生成getter方法而不生成setter方法(getter方法没有get前缀)
readwrite:默认属性,将生成不带额外参数的getter和setter方法(setter方法只有一个参数)。
atomic:对于对象的默认属性,就是setter/getter生成的方法是一个原子操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行setter全部语句之前,另一个线程开始执行setter的情况,相关于方法头尾加了锁一样。
nonatomic:不保证setter/getter的原子性,多线程情况下数据可能会有问题。nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。先释放原先变量,再将新变量&&&&& retain然后赋值;
注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:20595次
排名:千里之外
转载:10篇}

我要回帖

更多关于 objective c atomic 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信