这是来源于inessential.com的一系列博客,我觉得内容写的非常好,也非常有意义,所以我在此进行一系列的翻译。下面是原博客地址:http://inessential.com/hownottocrash
原文地址:
http://ifujun.com/yi-wen-ru-he-cai-neng-bu-beng-kui-6-properties-and-accessors/
http://inessential.com/2015/05/27/how_not_to_crash_6_properties_and_acce
这让我毛骨悚然:
- (void)someRandomMethod { some stuff… _thing = otherThing; other stuff… }
你可以证明这是正确的。你正在使用ARC,它会被适当的保持(retain)、释放(release)和添加(add)。没有人观察 _thing。
好吧。这合法并且它工作了。
你意识thing应该是可以被观察的。所以,每一个你设置thing的地方,你可以调用:
[self willChangeValueForKey:kThingKey];
_thing = otherThing;
[self didChangeValueForKey:kThingKey];
依然合法,并且可以工作。
问题是,在未来:今天之后,明天,或在6个月中,你或者其他人写了一个自定义的设置方法 - 也许因为当thing被设置的时候,你需要做类似于这样的事情self.needsDisplay = YES - 并且,现在你发现了一个bug,无论 thing什么时候被改变,视图都不会重绘。
或者,更糟糕的:也许,在未来,每当thing发生改变的时候,自定义的设置方法拆除了一个观察者,然后初始化了一个新的。当你直接设置_thing的时候,观察不会再保持正常,那么,你会遇到崩溃。
答案是一个简单的规则:在获得和设置属性的时候,使用存取器。
换句话说,这么做:
- (void)someRandomMethod { some stuff… self.thing = otherThing; other stuff… }
不管你是否拥有一个自定义的设置方法,这都会工作。当你设置thing的时候,你不需要关心其他方法。
(这是关于编程的简单的测试规则:如果你遵循它不会出错,但是你不遵循它就会出错,那么你应该遵循它。)
(不用关心存取器的性能问题。我是一个性能狂,我并没有发现这会成为一个问题。如果你的app有性能问题,剖析它,并找出真正的原因。)
例外
你不应该在这四个地方使用存取器:初始化方法、dealloc、自定义获取方法(custom getter)、自定义设置方法(custom setter)。这可以避免副作用。
如果你需要副作用 - 移除观察者,例如,在dealloc中 - 你通常放在设置方法里面,将它分离出来,然后在设置方法和dealloc中调用。(将观察者从初始化方法和dealloc中移出,可能标志着你的代码需要重构。)
自动合成
不要创建实例变量,永远。用属性申明代替。
属性自动合成实例变量。只在Xcode告诉你需要这么做的时候,再使用@synthesize 。
使用ARC
如果你有非ARC代码,升级到ARC方式。手动管理内存容易发生错误。甚至有些很多年工作经验的人依然会一次又一次的犯错误,错误导致了崩溃(或者内存泄露,或者内存被遗弃,最多)。
通常,我并不建议修改可以工作正常的代码 - 但是,如果你的代码需要手动管理,你自己或者和你的伙伴们一起将它转换为ARC。(每个人在手动管理内存的时候都会变得更糟。这没有任何一点会让你成为英雄。)
(转换到ARC之后可能会遇到性能问题,特别是你在循环里面处理大量的对象。记得使用自动释放池(autorelease pools)。不要急于下结论:使用性能分析工具。)
(另外,ARC转换器并不一定如你所愿。如果你使用它,要检查修改的内容。记得一次只转一个文件。Targets可以同时包含非ARC和ARC文件。)
不要这么做(Don’t do->this)
这会让我歇斯底里的吼叫:thing->property。不行。
dealloc
如果你不需要dealloc(由于你使用ARC),就不要创建它。不需要在dealloc中设置属性为nil。
一个很大的例外是代理:将代理置为nil。
使用弱引用
弱引用很棒。例如,代理,应该是弱引用。
父类应该持有它们的子类,但是子类对它的父类应该有一个弱引用(如果他们有引用的话)。弱引用可以让你避免这些 打破循环引用的无效方法。
不要在任何情况下使用unsafe_unretained。那是一个陷阱。你可能这么做:
#define CRASHING_BUG unsafe_unretained
从字面上说,这是不安全的。
不要使用它。见鬼 - 甚至不要碰它们。它们有一堆问题。