1,ARC 是编译器做的事情(在编译期间插入内存管理相关代码)
ARC evaluates the lifetime requirements of your objects and automatically inserts appropriate memory management calls for you at compile time
2,即使是局部指针变量(属性变量、局部变量 are strong
by default),所指对象引用计数也将+1
ARC ensures that oldLastName
is not deallocated before the NSLog
statement.
- (void)takeLastNameFrom:(Person *)person { |
NSString *oldLastname = [self lastName]; |
[self setLastName:[person lastName]]; |
NSLog(@"Lastname changed from %@ to %@", oldLastname, [self lastName]); |
} |
3,ARC仅仅维护了内存管理,其它的资源还是要手动置空或释放
(记得scrollview滑动时候退出页面 某些系统(因老的sdk中delegate为assign?)会crash)
You do not have to (indeed you cannot) release instance variables, but you may need to invoke [systemClassInstance setDelegate:nil]
on system classes and other code that isn’t compiled using ARC.
4,new是可以作为属性字段名的,需要重写get方法
// Won't work: |
@property NSString *newTitle; |
// Works: |
@property (getter=theNewTitle) NSString *newTitle; |
5,正确的书写格式
ClassName * qualifier variableName; 不过编译器也兼容了非标准形式
MyClass * __weak myWeakReference; |
MyClass * __unsafe_unretained myUnsafeReference; |
6,注意 __weak 的使用(__weak的设计是为了解引用)
NSString * __weak string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]]; |
NSLog(@"string: %@", string); |
string是个空值
7,避免强引用 Use Lifetime Qualifiers to Avoid Strong Reference Cycles
避免循环引用 Two better options are to either use __weak
, or set the __block
value to nil
to break the retain cycle.
example 7-1
MyViewController *myController = [[MyViewController alloc] init…];
|
// ...
|
MyViewController * __weak weakMyViewController = myController;
|
myController.completionHandler = ^(NSInteger result) {
|
[weakMyViewController dismissViewControllerAnimated:YES completion:nil];
|
};
|
example 7-2
For non-trivial cycles, however, you should use:(对于重要的回路或循环 应该对weak加strong)
这里讨论一个问题:
(1)循环引用是编译时 插入相关代码 进行内存管理的
(2) 块内的 MyViewController *strongMyController = weakMyController; 仅在运行时起作用 (引起引用计数+1)
(3) 尽管仅是在block执行期间引起对象的引用计数+1,仍旧会引起延迟释放的问题(本该立刻释放的,延迟释放了,这也是不能容忍的)
(4) For non-trivial cycles 重要的回路 究竟是指啥?如果该block确定定在主线程执行 貌似没啥可后怕;当线程重重入、并发的时候 貌似有问题,
但是 线程重重入、并发 可通过加锁解决问题;MyViewController *strongMyController = weakMyController;这句话的目的 究竟很在?
留个疑问在此!!!
MyViewController *myController = [[MyViewController alloc] init…];
|
// ...
|
MyViewController * __weak weakMyController = myController;
|
myController.completionHandler = ^(NSInteger result) {
|
MyViewController *strongMyController = weakMyController;
|
if (strongMyController) {
|
// ...
|
[strongMyController dismissViewControllerAnimated:YES completion:nil];
|
// ...
|
}
|
else {
|
// Probably nothing...
|
}
|
};
|
8,outlets 修饰的属性 除了顶层的需要strong 子试图使用week修饰
The patterns for declaring outlets in iOS and OS X change with ARC and become consistent across both platforms. The pattern you should typicallyadopt is: outlets should be weak
, except for those from File’s Owner to top-level objects in a nib file (or a storyboard scene) which should be strong
.
9,临时变量初始化默认值为nil (不包括NSInteger、int等)Stack Variables Are Initialized with nil
Using ARC, strong, weak, and autoreleasing stack variables are now implicitly initialized with nil
好习惯:手动指定初始值 如 int i =0;另外 这int i =0 也是必须的;因为初始值并不是0 是不确定的
10,编译器并没有自动化管理引用计数 Core Foundation下对象
The compiler does not automatically manage the lifetimes of Core Foundation objects
__bridge
__bridge_retained or CFBridgingRetain /CFRelease
__bridge_transfer CFBridgingRelease