可可坏习惯

时间:2008-10-15 16:21:01

标签: objective-c cocoa macos

自从你开始使用Cocoa进行编码后,你开发的那些坏习惯是什么?

我认为列出一些不良习惯并积极地添加它,更重要的是,打破这些习惯是产生代码质量的好方法。所以从现在开始,让你的坏习惯脱离你的胸膛。也许其他人分享你的坏习惯。

14 个答案:

答案 0 :(得分:21)

NULL传递给要求NSError**的参数,纯粹的懒惰。

答案 1 :(得分:14)

不够单元测试。如果没有单元测试,那么清理和重构代码真的很困难。如果没有不断的重构和清理,代码腐烂就会开始进入并传播。

使用单例模式共享对象,例如+ [MyObject defaultObject]。这本质上是一个全局变量,它可以产生一些很好的隐藏依赖关系和耦合。反过来,这会使代码更难以测试。

答案 2 :(得分:11)

使用控制流的例外

(以及其他非特殊情况。)

由于异常的使用在这里得到了另一个答案,并且评论中提到的documentation并没有特别强调这一点,因此值得强调的是,异常不应该用于正常的控制流程(因为在其他一些环境中很常见)。 Cocoa的例外情况相对而言非常昂贵。如果要传达错误,请使用NSError对象和Cocoa提供的error-handling architecture。不要抛出异常。

答案 3 :(得分:7)

以下是我的一些内容:

抛出异常而不试图抓住他们。我开始越来越多地依赖NSError来防止NSExceptions像John Woo电影中的子弹那样飞行,但我仍然有很多特殊的代码。

写一个快速课程来做X,Y& Z然后忘了清理dealloc。泄漏啊!

直接在各个地方使用字符串(KVO)而不是定义常量并使用它(有关更多信息,请参阅Dave Dribin在KVO上的优秀blog post

答案 4 :(得分:7)

我对在类中使用访问器感到懒惰。通常,最大的问题是我无法轻易地快速了解变量的范围。然后我上周花了几个小时来调试因使用

而导致的内存损坏问题
self.displayName = name

在某些地方和

displayName = name

在其他人。当我发现它并且我的应用程序停止崩溃时,我很高兴。我不是很高兴我浪费了几个小时寻找这样一个可以避免的错误。

答案 5 :(得分:5)

我经常使用#defines,我应该使用const声明。

另外,我可能有点过于多产我所投入的NSNotifications;脱钩跑了!

答案 6 :(得分:5)

坏习惯:保留我的Java心态。

我的Java背景导致我甚至在考虑使用变量做任何事情之前都要经常检查null,当我可以利用Objective-C的能力向nil发送消息时。 (见:"Sending a message to nil?"

我必须提醒自己,Objective-C允许我简单地编写优雅地使用返回值为0或nil的代码。

而不是尝试先发制人地抓住nil。

答案 7 :(得分:4)

你的意思是,除了咧嘴笑笑,当我能用10行做什么需要MFC编码器300?我想我对自己代码的最大抱​​怨是访问器的爆炸性增长;我做的下一个设计工作,我已经为自己设定了使用最少数量的属性的挑战。

答案 8 :(得分:4)

滥用绑定将模型对象属性彼此绑定。使用Bindings导致代码难以理解,难以调试且难以测试。仅使用绑定将UI绑定到Controller。如果需要解耦模型,请使用NSNotification而不是绑定。至少它比KVO更明确。

答案 9 :(得分:4)

硬编码字符串,如按钮/视图标题。纯粹的懒惰。现在需要了解所有内容以支持本地化:(

答案 10 :(得分:3)

我学会了讨厌Interface @#$% - er,因为它远没那么有用,而且比现在更多的错误,所以倾向于在代码中创建我的所有UI,坚定地仍然避免IB。这很愚蠢,因为我知道这会降低我的工作效率,但是我似乎不愿意花一个下午来学习如何将内容插入IB中。 (是的,我知道如何做这些简单的事情,但是当我有一些中等不太简单的事情要做时,我总是很生气,IB似乎对我不利。)

好的,你说服了我 - 本周末我将打破那个坏习惯。

谢谢! :)

答案 11 :(得分:2)

这有些通用,不一定是特定于可可,但是:

不能重构,因为必须更新.m和.h文件的懒惰。

XCode 3使某些类型的重构更容易重命名,但我发现自己的重构频率低于Java或C#,这是我试图破解的坏习惯。

答案 12 :(得分:2)

1)使用私有全局变量时,用下划线启动它们并将它们放在.m文件的接口部分中,如下所示:

@interface MyViewController (){
    NSArray *_tableData;
    NSNumberFormatter *_numberFormat;
}

2)仅将@properties用于全局公共变量和/或界面元素。

3)合成全局公共并按名称调用它们。

4)使用self.labelTitle NOT _labelTitle调用你的界面元素。

我使用这些变量命名约定的主要原因是因为我可以轻松查看变量并知道它的用途及其范围,但主要是解决XCode中您尝试重构的错误 - >在整个项目中重命名变量,它在此约定之外的某些情况下不起作用。

我重构了我的变量名A LOT,这个系统为我减轻了很多问题。

其他快速提示:

  • 将故事板用于您可能的所有内容,这可以缓解新版本中代码弃用的问题,并显着降低您的代码库总量。
  • 将您的控制器命名为VCMyName(视图控制器),NCMyName(导航控制器),TVMyName(tableview控制器)等。这比Apple的标准(MyNameViewController)更好,因为在最后添加全名通常会因为在很多接口中太长了。接口构建器正确解释建议的命名约定,调用视图“我的名字”。
  • 学习和使用核心数据,而不是您自己的make-shift SQLite查询系统,并创建一个辅助单元,用于访问一行或两行代码中的数据。
  • 不要将所有共享的应用程序代码放在AppDelegate中,这不是它的用途,而是创建一个AppController单元,并根据需要使用单例模式在视图中访问它。
  • 按照Apple's convention of passing data forward跟随下一个视图控制器并使用委托来处理返回的数据。这比在某处存储全局可访问数据要清晰得多。
  • 为您的项目创建一个Constants.h(仅限h文件),您可以在其中存储项目中使用的内容,例如标准行高等。此文件中只有#define。
  • 将登录数据存储在密钥链中,这样更安全,如果他们删除应用程序并完全重新安装,它仍然存在,您不必通过登录请求来对其进行错误处理。
  • 在NSUserDefaults中存储您的应用的自定义用户设置,这会将它们从您的数据库中取出,这样如果您有迁移/其他问题,这些数据(可能是您无法在应用中从头开始重新加载的唯一数据)受到影响。
  • 如果您将核心数据中的请求传递到视图,请将这些请求传递到视图中,这会使您的核心数据实体远离您的视图,并且还会带来性能优势。
  • 关注Apple's Cocoa conventions for variable and function names。如有疑问,请务必查看Apple是否有约定。

这些只是我的头脑。当然,有些人可能不同意我写的内容,但这些习惯在我开始时对我有用。

答案 13 :(得分:1)

我经常发现自己忘记输入构造函数的return self;部分。幸运的是,我已经开始打破这种特殊的习惯了。