您在编写 Objective-C 和 Cocoa 时使用了哪些最佳实践?

人气:552 发布:2022-10-16 标签: iphone ios cocoa objective-c cocoa-touch

问题描述

我知道 HIG(这很方便!),但是在编写 Objective-C 时,尤其是在使用 Cocoa(或 CocoaTouch)时,您使用了哪些编程实践.

I know about the HIG (which is quite handy!), but what programming practices do you use when writing Objective-C, and more specifically when using Cocoa (or CocoaTouch).

推荐答案

我已经开始做一些我认为不标准的事情:

There are a few things I have started to do that I do not think are standard:

1) 随着属性的出现,我不再使用_"作为私有"类变量的前缀.毕竟,如果一个变量可以被其他类访问,不应该有一个属性吗?我一直不喜欢让代码更难看的_"前缀,现在我可以省略它了.

1) With the advent of properties, I no longer use "_" to prefix "private" class variables. After all, if a variable can be accessed by other classes shouldn't there be a property for it? I always disliked the "_" prefix for making code uglier, and now I can leave it out.

2) 说到私有的东西,我更喜欢将私有方法定义放在 .m 文件中的类扩展中,如下所示:

2) Speaking of private things, I prefer to place private method definitions within the .m file in a class extension like so:

#import "MyClass.h"

@interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
@end

@implementation MyClass

为什么要在 .h 文件中塞满外人不应该关心的东西?空 () 适用于 .m 文件中的私有类别,如果您不实现声明的方法,则会发出编译警告.

Why clutter up the .h file with things outsiders should not care about? The empty () works for private categories in the .m file, and issues compile warnings if you do not implement the methods declared.

3) 我已将 dealloc 放在 .m 文件的顶部,就在 @synthesize 指令的下方.你dealloc不应该在你想在课堂上考虑的事情列表的顶部吗?在 iPhone 这样的环境中尤其如此.

3) I have taken to putting dealloc at the top of the .m file, just below the @synthesize directives. Shouldn't what you dealloc be at the top of the list of things you want to think about in a class? That is especially true in an environment like the iPhone.

3.5) 在表格单元格中,使每个元素(包括单元格本身)不透明以提高性能.这意味着在所有内容中设置适当的背景颜色.

3.5) In table cells, make every element (including the cell itself) opaque for performance. That means setting the appropriate background color in everything.

3.6) 当使用 NSURLConnection 时,通常你可能希望实现委托方法:

3.6) When using an NSURLConnection, as a rule you may well want to implement the delegate method:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
      return nil;
}

我发现大多数网络调用都是非常单一的,它比您希望缓存响应的规则更例外,尤其是对于网络服务调用.实现所示方法会禁用响应缓存.

I find most web calls are very singular and it's more the exception than the rule you'll be wanting responses cached, especially for web service calls. Implementing the method as shown disables caching of responses.

同样令人感兴趣的是 Joseph Mattiello 提供的一些针对 iPhone 的优秀技巧(在 iPhone 邮件列表中收到).还有更多,但这些是我认为最普遍有用的(请注意,现在对原始版本进行了一些轻微编辑,以包含回复中提供的详细信息):

Also of interest, are some good iPhone specific tips from Joseph Mattiello (received in an iPhone mailing list). There are more, but these were the most generally useful I thought (note that a few bits have now been slightly edited from the original to include details offered in responses):

4) 仅在必要时才使用双精度,例如在使用 CoreLocation 时.确保以 'f' 结束常量,以使 gcc 将它们存储为浮点数.

4) Only use double precision if you have to, such as when working with CoreLocation. Make sure you end your constants in 'f' to make gcc store them as floats.

float val = someFloat * 2.2f;

someFloat 实际上可能是双精度时,这一点最为重要,您不需要混合模式数学,因为您在存储中的 'val' 中丢失了精度.虽然 iPhone 的硬件支持浮点数,但与单精度相比,执行双精度算术可能仍需要更多时间.参考资料:

This is mostly important when someFloat may actually be a double, you don't need the mixed-mode math, since you're losing precision in 'val' on storage. While floating-point numbers are supported in hardware on iPhones, it may still take more time to do double-precision arithmetic as opposed to single precision. References:

iPhone 上的双重与浮动iPhone/iPad 双精度数学

在较旧的手机上,据说计算以相同的速度运行,但您可以在寄存器中拥有比双精度更多的单精度组件,因此对于许多计算而言,单精度最终会更快.

On the older phones supposedly calculations operate at the same speed but you can have more single precision components in registers than doubles, so for many calculations single precision will end up being faster.

5) 将您的属性设置为 nonatomic.默认情况下它们是atomic,在综合时,将创建信号量代码以防止多线程问题.99% 的人可能不需要担心这一点,并且当设置为非原子时,代码不会那么臃肿并且内存效率更高.

5) Set your properties as nonatomic. They're atomic by default and upon synthesis, semaphore code will be created to prevent multi-threading problems. 99% of you probably don't need to worry about this and the code is much less bloated and more memory-efficient when set to nonatomic.

6) SQLite 是一种非常非常快速的缓存大型数据集的方法.例如,地图应用程序可以将其切片缓存到 SQLite 文件中.最昂贵的部分是磁盘 I/O.通过在大块之间发送 BEGIN;COMMIT; 来避免许多小的写入.例如,我们使用 2 秒计时器,在每次新提交时重置.当它过期时,我们发送 COMMIT;,这会导致您的所有写入都集中在一大块中.SQLite 将事务数据存储到磁盘,并且执行 Begin/End 包装可以避免创建许多事务文件,将所有事务分组到一个文件中.

6) SQLite can be a very, very fast way to cache large data sets. A map application for instance can cache its tiles into SQLite files. The most expensive part is disk I/O. Avoid many small writes by sending BEGIN; and COMMIT; between large blocks. We use a 2 second timer for instance that resets on each new submit. When it expires, we send COMMIT; , which causes all your writes to go in one large chunk. SQLite stores transaction data to disk and doing this Begin/End wrapping avoids creation of many transaction files, grouping all of the transactions into one file.

另外,如果你的主线程上的 SQL 将阻塞你的 GUI.如果您有一个很长的查询,最好将您的查询存储为静态对象,并在单独的线程上运行您的 SQL.确保将任何修改数据库的查询字符串包装在 @synchronize() {} 块中.对于简短的查询,只需将内容留在主线程上即可更方便.

Also, SQL will block your GUI if it's on your main thread. If you have a very long query, It's a good idea to store your queries as static objects, and run your SQL on a separate thread. Make sure to wrap anything that modifies the database for query strings in @synchronize() {} blocks. For short queries just leave things on the main thread for easier convenience.

这里有更多的 SQLite 优化技巧,虽然文档看起来已经过时了,但很多点可能还是不错的;

More SQLite optimization tips are here, though the document appears out of date many of the points are probably still good;

http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html

916