目标C – 分配,复制,保留
我是Objective C的新手。我拥有C语言的基本知识,包括指针的概念。 我有两个基本的问题:
- 有人可以用一些比喻来解释分配,复制和保留之间的区别吗?
- 如何处理返回指针variables的函数,以及如何通过返回指针执行消息传递?
已更改的文档更新答案
信息现在分散在文档中的几个指南。 这是一个必读的列表:
- cocoa核心能力:声明的财产
- 用Objective-C编程:封装数据
- 过渡到ARC发行说明
- 高级内存pipe理编程指南
- Objective-C运行时编程指南:声明的属性
现在,这个问题的答案完全取决于您是否使用ARCpipe理的应用程序(新项目的现代默认值)或强制手动内存pipe理。
赋值vs弱 – 使用赋值来设置一个属性指针指向的对象的地址,而不保留它或以其他方式处理; 如果分配给它的对象被释放,使用weak可以使属性指向nil。 在大多数情况下,你会想要使用弱,所以你不试图访问一个释放对象(非法访问的内存地址 – “ EXC_BAD_ACCESS
”),如果你不执行适当的清理。
保留与复制 – 声明的属性默认使用保留 (所以你可以完全忽略它),并将自动pipe理对象的引用计数是否另一个对象分配给属性或设置为零; 使用副本自动发送新分配的对象一个-copy
消息(这将创build传递的对象的副本,并将该副本分配给属性,而不是 – 有用的(甚至是必需的)在某些情况下,分配的对象可能被修改后设置为某个其他对象的属性(这意味着该属性也将适用修改/突变)。
iOS参考库中的“ 内存pipe理编程指南”具有分配,复制和保留的基础知识,并附有类比和示例。
复制制作对象的副本,并返回保留数为1.如果复制对象,则拥有该副本。 这适用于任何包含单词copy的方法,其中“copy”指的是返回的对象。
保留将对象的保留计数增加1.获取对象的所有权。
释放将对象的保留计数减1。放弃对象的所有权。
复制vs分配vs保留
赋值是为BOOL,NSInteger或double等原始值。 对于使用保留或复制的对象,取决于是否要保留对原始对象的引用或复制它。
隐藏的function
NSString * string ;
当你调用这个expression式
string = @"Your name";
一个方法会自动调用
- (void)setString:(NSString*)newString { }
- 分配
在属性的setter方法中,将实例variables简单分配给新值,
- (void)setString:(NSString*)newString { string = newString; }
这可能会导致问题,因为Objective-C对象使用引用计数,因此通过不保留对象,有可能在您仍在使用它时释放该string。
- 保留
这在你的setter方法中保留了新的价值。 例如:这是更安全的,因为你明确声明你要维护对象的引用,并且在释放它之前你必须释放它。
- (void)setString:(NSString*)newString { [newString retain]; [string release]; string = newString; }
- 复制
这会在你的setter方法中创build一个string的副本:这通常与string一起使用,因为创build原始对象的副本可以确保在使用它时不会改变它。
- (void)setString:(NSString*)newString { if(string!=newString){ [string release]; string = [newString copy]; } }
·赋值是为BOOL,NSInteger或double等原始值。 对于使用保留或复制的对象,取决于是否要保留对原始对象的引用或复制它。 ·assign:在属性的setter方法中,有一个简单的实例variables赋值给新值,例如:
-(void)setString:(NSString*)newString{ string = newString; }
这可能会导致问题,因为Objective-C对象使用引用计数,因此通过不保留对象,有可能在您仍在使用它时释放该string。 保留:这将保留您的setter方法的新值。 例如:这是更安全的,因为你明确声明你要维护对象的引用,并且在释放它之前你必须释放它。
- (void)setString:(NSString*)newString{ [newString retain]; [string release]; string = newString; }
·复制:在setter方法中创build一个string的副本:这通常与string一起使用,因为创build原始对象的副本可确保在使用它时不会改变它。
- (void)setString:(NSString*)newString{ if(string!=newString){ [string release]; string = [newString copy]; } }
-
分配
- assign是一个默认属性属性
- assign是一个属性属性,告诉编译器如何综合属性的setter实现
-
复制:
- 当对象是可变的时,复制是必需的
- copy会返回一个你必须在非垃圾收集环境中明确释放的对象(例如dealloc)
- 您需要在完成后释放对象,因为您保留了该副本
-
保留:
- 指定在赋值时应将新值发送“-retain”,并将旧值发送给“-release”
- 如果你写保留它会自动工作像强
- 诸如“alloc”的方法包括一个隐含的“保留”
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"First",@"Second", nil]; NSMutableArray *copiedArray = [array mutableCopy]; NSMutableArray *retainedArray = [array retain]; [retainedArray addObject:@"Retained Third"]; [copiedArray addObject:@"Copied Third"]; NSLog(@"array = %@",array); NSLog(@"Retained Array = %@",retainedArray); NSLog(@"Copied Array = %@",copiedArray); array = ( First, Second, "Retained Third" ) Retained Array = ( First, Second, "Retained Third" ) Copied Array = ( First, Second, "Copied Third" )
保留与复制与分配
“ 分配 ”是默认值。 在由@synthesize创build的setter中,该值将被简单地分配给该属性。 我的理解是“分配”应该用于非指针属性。
当属性是指向对象的指针时,需要“ 保留 ”。 @synthesize生成的setter将保留(也就是添加保留计数)对象。 完成后您需要释放对象。
当对象是可变的时候需要“ 复制 ”。 如果此时需要对象的值,则可以使用此值,而不希望该值反映对象的其他所有者所做的任何更改。 您将需要释放对象,因为您保留副本。