我有兴趣更多地了解 iOS 中内存管理的实现和正确使用,特别是 Objective-C。
- 当您
-release
一个对象时,内存何时真正被释放并可供其他对象使用? - ARC 如何知道在编译期间将各种
-retain
和-release
消息插入/综合到代码中(以及它是否在编译期间发生,或者其他什么情况发生)时间)? - 我对
autorelease
的正确使用和目的有点不确定。例如,在编写返回数组的方法时,我通常在函数开头使用-alloc
和-init
该数组,然后return
它在最后。
例如:
- (NSArray *)myMethod {
NSMutableArray *theArray = [[NSMutableArray alloc] init];
// Do other stuff here
return theArray;
}
我也应该-autorelease
该数组吗?例如:
- (NSArray *)myMethod {
NSMutableArray *theArray = [[NSMutableArray alloc] init];
// Do other stuff here
return [theArray autorelease];
}
- 在什么情况下,最好在对象上使用便捷构造函数(例如
[NSArray array]
),而不是-alloc
和-init
对象? - 当创建一个新对象并将其分配给一个强属性时,我应该将其分配给一个中间变量而不是直接分配给该属性,以避免双重保留(一旦在
-alloc
和-init
,然后再次分配给strong
属性)?
例如,我应该这样做:
NSMutableArray *theNewArray = [[NSMutableArray alloc] init];
self.newArray = theNewArray;
而不是这个:
self.newArray = [[NSMutableArray alloc] init];
在此先感谢您对这些问题的任何帮助!
最佳答案
一旦对象被释放,内存就可供其他人使用。后者发生在它的保留计数达到 0 时,也就是说,每次它被保留时都有一个释放。
在 Objective-C 中有一个命名约定,每当您调用名称中包含“alloc”、“copy”或“new”的方法时,您就拥有已创建的对象,并且您拥有一段时间后发布它的责任。此外,当你调用一个以你想要接收的东西的名称开头的方法时(即工厂方法,如 [NSString stringWithFormat:]、[NSDate date] 等),返回的对象总是自动释放的,这意味着您不必担心释放它。
这些命名规则变得如此重要并且得到了很好的遵守,以至于当 ARC 出现时,Apple 能够在 ARC 本身中构建它们。因此,在编译期间,ARC 会在正确的位置为您插入发布、自动发布和保留。
Autorelease 将对象标记为稍后(在下一个运行循环中)释放,而不是像常规释放那样立即释放。该对象与其他已自动释放的对象一起添加到自动释放池中。在 ARC 之前,当您从方法返回您拥有所有权的对象(即通过 alloc、copy 或 new 创建)时,您将使用 autorelease。如果只是正常释放它,那么该对象可能会在它能够被调用函数使用之前被释放。使用 ARC,您不必担心任何这些事情,只需直接返回对象即可。
有时候工厂时间更方便。 [NSString stringWithFormat:] 让你初始化一个字符串传递占位符。 [NSDate date] 返回已初始化的当前日期。如果您在这些情况下分配/初始化,则必须额外增加一两行代码才能获得相同的结果。在使用 ARC 的世界中,这些情况下的内存管理根本不再重要。
不用担心。你可以直接分配它。编译器将优化保留/释放。
关于ios - Objective-C/iOS 内存管理问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32555591/