我知道HIG(这非常方便!),但是在编写Objective-C时,更具体地说,在使用Cocoa(或CocoaTouch)时,您使用了什么编程实践?
当前回答
想想nil值
正如这个问题所指出的,到nil的消息在Objective-C中是有效的。虽然这通常是一个优势——导致更干净和更自然的代码——但如果您在意想不到的情况下获得nil值,该功能偶尔会导致特殊且难以追踪的错误。
其他回答
简单但经常被遗忘。根据规格:
一般来说,方法各不相同 具有相同选择器的类 (相同的名字)也必须共享 相同的返回值和参数类型。这 约束是由编译器施加的 允许动态绑定。
在这种情况下,所有相同的命名选择器,即使在不同的类中,也会被认为具有相同的返回/参数类型。这里有一个简单的例子。
@interface FooInt:NSObject{}
-(int) print;
@end
@implementation FooInt
-(int) print{
return 5;
}
@end
@interface FooFloat:NSObject{}
-(float) print;
@end
@implementation FooFloat
-(float) print{
return 3.3;
}
@end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id f1=[[FooFloat alloc]init];
//prints 0, runtime considers [f1 print] to return int, as f1's type is "id" and FooInt precedes FooBar
NSLog(@"%f",[f1 print]);
FooFloat* f2=[[FooFloat alloc]init];
//prints 3.3 expectedly as the static type is FooFloat
NSLog(@"%f",[f2 print]);
[f1 release];
[f2 release]
[pool drain];
return 0;
}
如果您使用的是Leopard (Mac OS X 10.5)或更高版本,则可以使用Instruments应用程序来查找和跟踪内存泄漏。在Xcode中构建程序后,选择使用性能工具> Leaks运行>。
即使你的应用程序没有显示任何泄漏,你可能把对象保存得太久了。在Instruments中,您可以为此使用ObjectAlloc工具。在Instruments文档中选择ObjectAlloc乐器,并通过选择View > detail(它旁边应该有一个复选标记)来显示乐器的详细信息(如果还没有显示的话)。在ObjectAlloc详细信息中的“分配生命周期”下,确保选择“已创建和仍然存在”旁边的单选按钮。
现在,每当您停止记录应用程序时,选择ObjectAlloc工具将在“# Net”列中显示对应用程序中每个仍然活动的对象的引用数。确保不仅要查看自己的类,还要查看NIB文件的顶级对象的类。例如,如果你在屏幕上没有窗口,而你看到一个仍然存在的NSWindow的引用,你可能没有在你的代码中释放它。
确保您收藏了调试魔术页面。这应该是你在寻找Cocoa bug的源头时碰壁的第一站。
例如,它会告诉你如何找到你第一次分配内存的方法,后来导致崩溃(比如在应用程序终止期间)。
避免生成
Since you typically(1) don't have direct control over their lifetime, autoreleased objects can persist for a comparatively long time and unnecessarily increase the memory footprint of your application. Whilst on the desktop this may be of little consequence, on more constrained platforms this can be a significant issue. On all platforms, therefore, and especially on more constrained platforms, it is considered best practice to avoid using methods that would lead to autoreleased objects and instead you are encouraged to use the alloc/init pattern.
因此,而不是:
aVariable = [AClass convenienceMethod];
在可能的情况下,你应该使用:
aVariable = [[AClass alloc] init];
// do things with aVariable
[aVariable release];
当您编写自己的方法返回新创建的对象时,您可以利用Cocoa的命名约定,通过在方法名前加上“new”来标记接收方必须释放该对象。
因此,与其:
- (MyClass *)convenienceMethod {
MyClass *instance = [[[self alloc] init] autorelease];
// configure instance
return instance;
}
你可以这样写:
- (MyClass *)newInstance {
MyClass *instance = [[self alloc] init];
// configure instance
return instance;
}
因为方法名以"new"开头,你的API的使用者知道他们负责释放接收到的对象(例如,看NSObjectController的newObject方法)。
你可以通过使用你自己的本地自动释放池来控制。有关这方面的更多信息,请参见自动释放池。
根据用户需要对字符串进行排序
在对要呈现给用户的字符串进行排序时,不应该使用简单的compare:方法。相反,你应该总是使用本地化比较方法,如localizedCompare:或localizedcaseinsensitiveecompare:。
有关详细信息,请参见搜索、比较和排序字符串。
推荐文章
- 如何删除默认的导航栏空间在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失败