我知道HIG(这非常方便!),但是在编写Objective-C时,更具体地说,在使用Cocoa(或CocoaTouch)时,您使用了什么编程实践?
当前回答
对于初学者来说,一个很明显的方法是:利用Xcode的自动缩进功能。即使是从其他源复制/粘贴代码,粘贴完代码后,也可以选择整个代码块,右键单击它,然后选择选项重新缩进该代码块中的所有内容。
Xcode会解析这个section并根据括号,循环等缩进它。这比每一行都按空格键或tab键要有效率得多。
其他回答
这是一个微妙但很方便的方法。如果你将自己作为委托传递给另一个对象,在dealloc之前重置该对象的委托。
- (void)dealloc
{
self.someObject.delegate = NULL;
self.someObject = NULL;
//
[super dealloc];
}
这样做可以确保不再发送更多的委托方法。当您即将dealloc并消失在以太中时,您希望确保没有任何东西可以意外地向您发送更多消息。还记得自己。someObject可以被另一个对象保留(它可以是一个单例对象或在自动释放池中或其他任何对象),直到您告诉它“停止向我发送消息!”,它才会认为您即将被释放的对象是公平的游戏。
养成这种习惯将使您避免大量令人痛苦的调试的奇怪崩溃。
同样的原理也适用于键值观察和NSNotifications。
编辑:
更有防御性的改变:
self.someObject.delegate = NULL;
成:
if (self.someObject.delegate == self)
self.someObject.delegate = NULL;
变量和属性
1/保持头文件整洁,隐藏实现 不要在头文件中包含实例变量。作为属性放入类延续中的私有变量。公共变量在头文件中声明为公共属性。 如果它应该是只读的,将其声明为readonly,并在类延续中将其重写为readwrite。 基本上我根本不用变量,只用属性。
2/给你的属性一个非默认变量名,例如:
@synthesize property = property_;
原因1:在分配属性时,您将捕获由于忘记“self.”而引起的错误。 原因2:从我的实验中,仪器中的泄漏分析仪在检测默认名称的泄漏属性时存在问题。
3/不要在属性上直接使用retain或release(或仅在非常特殊的情况下)。在dealloc中,给它们分配一个nil。保留属性意味着自己处理保留/释放。例如,您永远不知道setter是否没有添加或删除观察器。您应该只在它的setter和getter中直接使用变量。
的观点
1/如果可以的话,将每个视图定义放入xib中(例外通常是动态内容和层设置)。它节省时间(比写代码简单),易于更改,并保持代码整洁。
2/不要试图通过减少视图数量来优化视图。不要在代码中创建UIImageView而不是xib,因为你想在其中添加子视图。使用UIImageView作为背景。视图框架可以毫无问题地处理数百个视图。
3/ iboutlet不需要总是被保留(或强大)。注意,大多数iboutlet都是视图层次结构的一部分,因此隐式保留。
4/释放viewDidUnload中的所有iboutlet
5/从dealloc方法调用viewDidUnload。它不是隐式调用的。
内存
1/创建对象时自动释放对象。许多错误是由于将释放调用移动到一个if-else分支或在返回语句之后引起的。释放而不是自动释放应该只在特殊情况下使用——例如,当你在等待一个运行循环时,你不想让你的对象过早被自动释放。
2/即使你在使用自动引用计数,你也必须完全理解保留-释放方法是如何工作的。手动使用保留-释放并不比ARC更复杂,在这两种情况下,您都必须考虑泄漏和保留周期。 考虑在大型项目或复杂的对象层次结构上手动使用保留释放。
评论
1/让你的代码自动文档化。 每个变量名和方法名都应该说明它在做什么。如果代码编写正确(这方面需要大量实践),则不需要任何代码注释(与文档注释不同)。算法可能很复杂,但代码应该总是简单的。
2/有时候,你需要别人的评论。通常用来描述一种不明显的代码行为或黑客行为。如果您觉得必须写注释,首先尝试重写代码,使其更简单,不需要注释。
缩进
1/不要增加太多缩进。 大多数方法代码应该在方法级别上缩进。嵌套块(if, for等)降低了可读性。如果您有三个嵌套块,您应该尝试将内部块放入一个单独的方法中。四个或更多嵌套的块永远不应该使用。 如果大部分方法代码都在If中,则对If条件求反,例如:
if (self) {
//... long initialization code ...
}
return self;
if (!self) {
return nil;
}
//... long initialization code ...
return self;
了解C代码,主要是C结构
注意Obj-C只是C语言之上的一个轻量级OOP层。你应该了解C语言的基本代码结构(枚举、结构体、数组、指针等)是如何工作的。 例子:
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height + 20);
等于:
CGRect frame = view.frame;
frame.size.height += 20;
view.frame = frame;
还有更多
维护自己的编码标准文档,并经常更新它。试着从错误中学习。理解错误产生的原因,并尝试使用编码标准来避免它。
我们的编码标准目前大约有20页,混合了Java编码标准,谷歌Obj-C/ c++标准和我们自己的添加。记录你的代码,在正确的地方使用标准的缩进,空格和空行等等。
IBOutlets
从历史上看,outlet的内存管理一直很差。 当前的最佳实践是将outlet声明为属性:
@interface MyClass :NSObject {
NSTextField *textField;
}
@property (nonatomic, retain) IBOutlet NSTextField *textField;
@end
使用属性使内存管理语义清晰;如果使用实例变量综合,它还提供了一致的模式。
想想nil值
正如这个问题所指出的,到nil的消息在Objective-C中是有效的。虽然这通常是一个优势——导致更干净和更自然的代码——但如果您在意想不到的情况下获得nil值,该功能偶尔会导致特殊且难以追踪的错误。
黄金法则:如果你分配了,那么你就释放了!
更新:除非你正在使用ARC
推荐文章
- 如何删除默认的导航栏空间在SwiftUI导航视图
- 如何在iOS中使用Swift编程segue
- Swift -整数转换为小时/分钟/秒
- Swift:声明一个空字典
- 为什么ARC仍然需要@autoreleasepool ?
- 在成功提交我的应用程序后,“太多符号文件”
- 首先添加一个UIView,甚至是导航栏
- 我如何改变UIButton标题颜色?
- 如何从UIImage (Cocoa Touch)或CGImage (Core Graphics)获取像素数据?
- 在Swift中如何调用GCD主线程上的参数方法?
- NSLayoutConstraints是可动画的吗?
- iOS -构建失败,CocoaPods无法找到头文件
- Xcode 4挂在“附加到(应用程序名称)”
- 为什么单元测试中的代码不能找到包资源?
- CFNetwork SSLHandshake iOS 9失败