我知道HIG(这非常方便!),但是在编写Objective-C时,更具体地说,在使用Cocoa(或CocoaTouch)时,您使用了什么编程实践?


当前回答

简单但经常被遗忘。根据规格:

一般来说,方法各不相同 具有相同选择器的类 (相同的名字)也必须共享 相同的返回值和参数类型。这 约束是由编译器施加的 允许动态绑定。

在这种情况下,所有相同的命名选择器,即使在不同的类中,也会被认为具有相同的返回/参数类型。这里有一个简单的例子。

@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;
}   

其他回答

我知道我在第一次接触Cocoa编程时忽略了这一点。

确保您了解有关NIB文件的内存管理职责。您负责释放所加载的任何NIB文件中的顶级对象。阅读苹果关于这个主题的文档。

在dealloc中清理。

这是最容易忘记的事情之一——尤其是在以150英里/小时的速度编码时。总是,总是,总是清理dealloc中的属性/成员变量。

我喜欢使用Objc 2属性-新的点表示法-所以这使得清理变得无痛。通常很简单:

- (void)dealloc
{
    self.someAttribute = NULL;
    [super dealloc];
}

这将为您处理发布,并将属性设置为NULL(我认为这是防御性编程——以防dealloc中的另一个方法再次访问成员变量——很少,但也可能发生)。

在10.5中打开GC后,就不再需要这么多了——但是你可能仍然需要清理你创建的其他资源,你可以在finalize方法中做这件事。

尽量避免我现在决定称之为“新类别yaholism”的现象。当Objective-C的新手发现类别时,他们通常会疯狂地为现有的每个类添加有用的小类别(“什么?我可以添加一个方法来转换一个数字到罗马数字到NSNumber岩石上!”)。

不要这样做。

你的代码将更容易移植,更容易理解,因为没有几十个小类别方法散布在20多个基础类之上。

大多数时候,当你真的认为你需要一个类别方法来帮助简化一些代码时,你会发现你永远不会重用这个方法。

还有其他的危险,除非你对你的分类方法进行命名空间(除了疯狂的ddribin,还有谁会这么做呢?),在你的地址空间中运行的苹果、插件或其他东西也有可能用相同的名称定义相同的分类方法,但副作用略有不同....

好的。现在你已经被警告过了,忽略“不要做这部分”。但是要极度克制。

确保您收藏了调试魔术页面。这应该是你在寻找Cocoa bug的源头时碰壁的第一站。

例如,它会告诉你如何找到你第一次分配内存的方法,后来导致崩溃(比如在应用程序终止期间)。

使用标准的Cocoa命名和格式化约定和术语,而不是使用其他环境中使用的任何术语。有很多Cocoa开发人员,当他们中的另一个人开始使用您的代码时,如果它看起来和感觉上与其他Cocoa代码相似,那么它将更容易接近。

做什么和不做什么的例子:

Don't declare id m_something; in an object's interface and call it a member variable or field; use something or _something for its name and call it an instance variable. Don't name a getter -getSomething; the proper Cocoa name is just -something. Don't name a setter -something:; it should be -setSomething: The method name is interspersed with the arguments and includes colons; it's -[NSObject performSelector:withObject:], not NSObject::performSelector. Use inter-caps (CamelCase) in method names, parameters, variables, class names, etc. rather than underbars (underscores). Class names start with an upper-case letter, variable and method names with lower-case.

无论你做什么,不要使用Win16/ win32风格的匈牙利符号。甚至微软也在转向。net平台时放弃了这一点。