我知道HIG (这很是方便!),可是在编写Objective-C时使用了什么编程实践,更具体地说,在使用Cocoa(或CocoaTouch)时。 html
黄金法则:若是你alloc
那么你release
! web
更新:除非您使用ARC sql
我开始作的一些事情我不认为是标准的: 数据库
1)随着属性的出现,我再也不使用“_”来加上“私有”类变量的前缀。 毕竟,若是一个变量能够被其余类访问,那么它应该没有属性吗? 我老是不喜欢使用“_”前缀来使代码变得更加丑陋,如今我能够把它留下来。 编程
2)说到私有事物,我更喜欢将.m文件中的私有方法定义放在类扩展中,以下所示: 缓存
#import "MyClass.h" @interface MyClass () - (void) someMethod; - (void) someOtherMethod; @end @implementation MyClass
为何用外人不该该关心的东西来混淆.h文件? empty()适用于.m文件中的私有类,若是不实现声明的方法,则发出编译警告。 多线程
3)我已经将dealloc放在.m文件的顶部,就在@synthesize指令的下面。 你不该该把你想要在课堂上想到的东西放在最重要的位置吗? 在像iPhone这样的环境中尤为如此。 性能
3.5)在表格单元格中,使每一个元素(包括单元格自己)对性能不透明。 这意味着在全部内容中设置适当的背景颜色。 大数据
3.6)使用NSURLConnection时,一般您可能但愿实现委托方法: 优化
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { return nil; }
我发现大多数Web调用都是很是单一的,而且它比您但愿缓存响应的规则更为例外,尤为是对于Web服务调用。 实现如图所示的方法会禁用响应的缓存。
一样有趣的是,Joseph Mattiello的一些优秀的iPhone特定提示(在iPhone邮件列表中收到)。 还有更多,但这些是我认为最广泛有用的(请注意,如今已经从原始版本略微编辑了一些内容以包含响应中提供的详细信息):
4)若是必须,只使用双精度,例如使用CoreLocation时。 确保以'f'结束常量以使gcc将它们存储为浮点数。
float val = someFloat * 2.2f;
当someFloat
实际上多是一个double时,这一点很是重要,你不须要混合模式数学,由于你在存储上的'val'精度会失去。 虽然iPhone上的硬件支持浮点数,但与单精度相比,双精度算术可能仍须要更多时间。 参考文献:
在较旧的手机上,听说计算以相同的速度运行,可是你能够在寄存器中拥有比双精度更多的单精度元件,所以对于许多计算,单精度最终会更快。
5)将属性设置nonatomic
属性。 默认状况下它们是atomic
的,在合成时,将建立信号量代码以防止出现多线程问题。 99%的人可能不须要担忧这一点,而且当设置为非原子时,代码不那么臃肿,内存效率更高。
6)SQLite能够是一种很是快速的缓存大数据集的方法。 例如,地图应用程序能够将其图块缓存到SQLite文件中。 最昂贵的部分是磁盘I / O. 经过发送BEGIN;
避免许多小写BEGIN;
和COMMIT;
大块之间。 例如,咱们使用2秒计时器重置每一个新提交。 到期时,咱们发送COMMIT; ,这会致使全部写入都进入一个大块。 SQLite将事务数据存储到磁盘并执行此开始/结束包装可避免建立许多事务文件,将全部事务分组到一个文件中。
此外,若是您的GUI位于主线程上,SQL将阻止您的GUI。 若是您有一个很长的查询,最好将查询存储为静态对象,并在单独的线程上运行SQL。 确保在@synchronize() {}
块中包装修改数据库的任何内容以查询字符串。 对于简短的查询,只需将内容留在主线程上以方便使用。
这里有更多的SQLite优化技巧,虽然文档显得过期,但许多要点可能仍然不错;
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html
@kendell
代替:
@interface MyClass (private) - (void) someMethod - (void) someOtherMethod @end
使用:
@interface MyClass () - (void) someMethod - (void) someOtherMethod @end
Objective-C 2.0中的新功能。
Apple的Objective-C 2.0参考中描述了类扩展。
“类扩展容许您在主类@interface块之外的位置为类声明其余必需的API”
因此它们是实际课程的一部分 - 而不是课堂上的(私人)课程。 微妙但重要的区别。
在dealloc清理。
这是最容易忘记的事情之一 - 尤为是 当编码为150英里每小时。 始终,始终,始终清理dealloc中的属性/成员变量。
我喜欢使用Objc 2属性 - 使用新的点符号 - 因此这使得清理无痛。 一般很简单:
- (void)dealloc { self.someAttribute = NULL; [super dealloc]; }
这将照顾你的释放并将属性设置为NULL(我考虑防护性编程 - 若是dealloc中的另外一个方法再次访问成员变量 - 不多但可能发生)。
在10.5中打开GC时,再也不须要这么多 - 但您可能仍须要清理您建立的其余资源,您能够在finalize方法中执行此操做。
这是微妙的,但很方便。 若是您将本身做为委托传递给另外一个对象,请在dealloc
以前重置该对象的委托。
- (void)dealloc { self.someObject.delegate = NULL; self.someObject = NULL; // [super dealloc]; }
经过这样作,您能够确保再也不发送任何委托方法。 当你即将dealloc
并消失在以太中时,你要确保没有任何东西能够偶然发送给你更多的消息。 记住self.someObject能够被另外一个对象保留(它能够是单例或自动释放池或其余任何对象),直到你告诉它“中止向我发送消息!”,它认为你刚刚被释放的对象是公平的游戏。
养成这种习惯能够避免许多奇怪的崩溃,这些都是很难调试的。
一样的原则也适用于Key Value Observation和NSNotifications。
编辑:
更具防护性的变化:
self.someObject.delegate = NULL;
成:
if (self.someObject.delegate == self) self.someObject.delegate = NULL;