使用ARC时一定要记住,引用计数实际上还是要执行的,只不过保留与释放操作现在是由ARC自动为你添加。
所以直接在ARC下调用这些内存管理方法是非法的:
- (instancetype)retain OBJC_ARC_UNAVAILABLE;
- (oneway void)release OBJC_ARC_UNAVAILABLE;
- (instancetype)autorelease OBJC_ARC_UNAVAILABLE;
- (void)dealloc OBJC_SWIFT_UNAVAILABLE("use 'deinit' to define a de-initializer");
/**
实际上,ARC在调用这些方法时,并不通过普通的Objective-C消息派发机制,而是直接调用其底层C语言版本。
*/
使用ARC时必须遵循的方法命名规则
-
若方法名以下列词语开头,则其返回值的对象归调用者所有,调用者要负责释放方法所返回的对象:
- alloc
- new
- copy
- mutableCopy
-
ARC通过命名约定将内存管理规则标准化。
-
ARC还可以执行一些手工操作很难甚至无法完成的优化。
-
ARC也包含运行期组件。
-
在方法中返回自动释放的对象时,要执行objc_autoreleaseRetainValue函数。此函数会检视当前方法返回之后即将要执行的那段代码。若发现那段代码要在返回的对象上执行retain操作,则设置全局数据节后(此数据结构的具体内容因处理器而异)中的一个标志位,而不执行autorelease操作。
-
与之相似,如果方法返回了一个自动释放的对象,而调用方法的代码要保留此对象,执行objc_retainAutoreleasedReturnValue函数。此函数要检测刚才提到的那个标志位,若已经置位,则不执行retain操作。
-
设置并检测标志位,要比调用autorelease和retain更快。
-
- (EOCPerson *)personWithName:(NSString *)name
{
EOCPerson * person = [[EOCPerson alloc] init];
person.name = name;
objc_autoreleaseReturnValue(person);
return nil;
}
EOCPerson *tmp = [EOCPerson personWithName:@"Matt Galloway"];
_myPerson = objc_retainAutoreleasedReturnValue(tmp);
变量的内存管理语义
-
__string:默认语义,保留此值。
-
__unsafe_unretained:不保留此值,这么做可能不安全,因为等到再次使用变量时,其对象可能已经回收了。
-
__weak:不保留此值,但是变量可以安全使用,因为如果系统把这个对象回收了,那么变量也会自动清空。
-
__autoreleasing:把对象“按引用传递”(pass by reference)给方法时,使用这个特殊的修饰符。此值在方法返回时自动释放。
-
可以用__weak局部变量来打破由“块”(block)所引入的保留环。
ARC如何清了实例变量
-
用了ARC之后,就不需要再编写来释放强引用的dealloc方法了。
-
编译器如果发现某个对象里含有C++对象,就会生成名为.cxx_destruce的方法。而ARC则借助此特性来生成清理例程(cleanup routine)。在该方法中生成清理内存所需代码。
-
非Objective-C的对象,比如CoreFoundation中的对象或是由malloc()分配在堆中的内存,那么仍然需要清理。
////ARC模式下的内存管理
- (void)dealloc
{
/**
ARC会自动在.cxx_destruct方法中生成代码并运行此方法,而在生成的代码中会自动调用超类的dealloc方法,不需要像原来那样调用超类的dealloc方法
*/
CFRelease(_coreFoundationObject);
free(_heapAllocatedMemeoryBlob);
}
要点
-
有ARC之后,程序员就无需担心内存管理问题了。使用ARC来编程,可省去类中的许多“样板代码”。
-
ARC管理对象生命期的办法基本上就是:在合适的地方插入“保留”及“释放”操作。在ARC环境下,变量的内存管理语义可以通过修饰符指明,而原来则需要手工执行“保留”和“释放”操作。
-
由方法所返回的对象,其内存管理语义总是通过方法名来体现。ARC将此确定为开发者必须遵守的规则。
-
ARC只负责管理Objective-C对象的内存。尤其要注意:CoreFoundation对象不归ARC管理,开发者必须适时调用CFRetain/CFRelease。
网友评论