我知道HIG(这非常方便!),但是在编写Objective-C时,更具体地说,在使用Cocoa(或CocoaTouch)时,您使用了什么编程实践?
当前回答
不要使用未知字符串作为格式字符串
当方法或函数接受格式字符串参数时,应确保能够控制格式字符串的内容。
例如,当记录字符串时,很容易将字符串变量作为唯一参数传递给NSLog:
NSString *aString = // get a string from somewhere;
NSLog(aString);
这样做的问题是,字符串可能包含被解释为格式字符串的字符。这可能导致错误的输出、崩溃和安全问题。相反,你应该将字符串变量替换为一个格式字符串:
NSLog(@"%@", aString);
其他回答
如果您使用的是Leopard (Mac OS X 10.5)或更高版本,则可以使用Instruments应用程序来查找和跟踪内存泄漏。在Xcode中构建程序后,选择使用性能工具> Leaks运行>。
即使你的应用程序没有显示任何泄漏,你可能把对象保存得太久了。在Instruments中,您可以为此使用ObjectAlloc工具。在Instruments文档中选择ObjectAlloc乐器,并通过选择View > detail(它旁边应该有一个复选标记)来显示乐器的详细信息(如果还没有显示的话)。在ObjectAlloc详细信息中的“分配生命周期”下,确保选择“已创建和仍然存在”旁边的单选按钮。
现在,每当您停止记录应用程序时,选择ObjectAlloc工具将在“# Net”列中显示对应用程序中每个仍然活动的对象的引用数。确保不仅要查看自己的类,还要查看NIB文件的顶级对象的类。例如,如果你在屏幕上没有窗口,而你看到一个仍然存在的NSWindow的引用,你可能没有在你的代码中释放它。
编写单元测试。您可以在Cocoa中测试许多在其他框架中可能比较困难的事情。例如,对于UI代码,您通常可以验证事物是否按照应有的方式连接,并相信它们在使用时能够正常工作。你可以很容易地设置状态和调用委托方法来测试它们。
在编写内部测试时,也不会有公共、受保护和私有方法可见性。
功能性更强。
Objective-C是面向对象的语言,但是Cocoa框架是函数式风格的,并且在很多情况下是函数式设计的。
There is separation of mutability. Use immutable classes as primary, and mutable object as secondary. For instance, use NSArray primarily, and use NSMutableArray only when you need. There is pure functions. Not so many, buy many of framework APIs are designed like pure function. Look at functions such as CGRectMake() or CGAffineTransformMake(). Obviously pointer form looks more efficient. However indirect argument with pointers can't offer side-effect-free. Design structures purely as much as possible. Separate even state objects. Use -copy instead of -retain when passing a value to other object. Because shared state can influence mutation to value in other object silently. So can't be side-effect-free. If you have a value from external from object, copy it. So it's also important designing shared state as minimal as possible.
但是也不要害怕使用不纯函数。
There is lazy evaluation. See something like -[UIViewController view] property. The view won't be created when the object is created. It'll be created when caller reading view property at first time. UIImage will not be loaded until it actually being drawn. There are many implementation like this design. This kind of designs are very helpful for resource management, but if you don't know the concept of lazy evaluation, it's not easy to understand behavior of them. There is closure. Use C-blocks as much as possible. This will simplify your life greatly. But read once more about block-memory-management before using it. There is semi-auto GC. NSAutoreleasePool. Use -autorelease primary. Use manual -retain/-release secondary when you really need. (ex: memory optimization, explicit resource deletion)
想想nil值
正如这个问题所指出的,到nil的消息在Objective-C中是有效的。虽然这通常是一个优势——导致更干净和更自然的代码——但如果您在意想不到的情况下获得nil值,该功能偶尔会导致特殊且难以追踪的错误。
对于初学者来说,一个很明显的方法是:利用Xcode的自动缩进功能。即使是从其他源复制/粘贴代码,粘贴完代码后,也可以选择整个代码块,右键单击它,然后选择选项重新缩进该代码块中的所有内容。
Xcode会解析这个section并根据括号,循环等缩进它。这比每一行都按空格键或tab键要有效率得多。
推荐文章
- 如何删除默认的导航栏空间在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失败