【问题标题】:Where's the best place to store constants in an iOS app?在 iOS 应用程序中存储常量的最佳位置在哪里?
【发布时间】:2012-02-12 17:14:19
【问题描述】:

我正在开发一个从 JSON API 获取资源的应用程序。

所有资源都具有相同的基本 URL:

http://api.mysite.com/resources.json
http://api.mysite.com/other_resources.json

我想存储 http://api.mysite.com/ 字符串,以便我的所有控制器和模型都可以使用它,从而在编写资源 URL 时消除一些重复。

最好的地方是哪里? -prefix.pch 文件?

任何建议表示赞赏

【问题讨论】:

    标签: objective-c ios


    【解决方案1】:

    我同意亚历克斯·科普兰的回答,但有一个重要补充。

    将所有常量放入一个名为“Constants.h”(或您想要的)的文件中

    编辑:

    • 三年前,当我回答这个问题时,我正处于 #define 的潮流中,请查看下面的修订版本。

    常量.h

    #define kFilterDate @"date"
    #define kFilterRadius @"radius"
    #define kFilterSort @"sort"
    
    //Global Strings
    #define kDividingString @" / "
    
    //Strings
    #define kTour @"Tour"
    #define kToursKey @"tours"
    

    但是不要将它导入到任何你需要的文件中,而是将它导入到你的前缀文件中,这样你的所有标题都会在你的整个项目中自动导入它。

    Project_Prefix.pch

    //
    // Prefix header for all source files of the project
    //
    
    #ifdef __OBJC__
        #import <Foundation/Foundation.h>
        #import <UIKit/UIKit.h>
        #import "Constants.h"
    #endif
    

    修订

    尽管之前的所有信息仍然有效,但我们可以做一些事情来让我们的常量更加安全。

    使用 const 变量在 Constants.h 文件中创建常量

    //Filters
    FOUNDATION_EXPORT NSString *const kFilterDate;
    FOUNDATION_EXPORT NSString *const kFilterRadius;
    FOUNDATION_EXPORT NSString *const kFilterSort;
    
    //Global Strings
    FOUNDATION_EXPORT NSString *const kDividingString;
    
    //Strings
    FOUNDATION_EXPORT NSString *const kTour;
    FOUNDATION_EXPORT NSString *const kToursKey;
    

    Constants.m

    //Filters
    NSString *const kFilterDate = @"date";
    NSString *const kFilterRadius = @"radius";
    NSString *const kFilterSort = @"sort";
    
    //Global Strings
    NSString *const kDividingString = @" / ";
    
    //Strings
    NSString *const kTour = @"Tour";
    NSString *const kToursKey = @"tours";
    

    这仍然可以像上面一样导入到您的前缀文件中,但只能使用文件中真正全局的常量来执行此操作。在许多地方经常使用的那些。将所有常量转储到此文件中将导致使用任何常量的代码耦合到常量文件。因此,如果您尝试重用代码,则必须附带常量文件。这并不总是坏事,而且很多时候都是有意的(这很好),但限制依赖总是一个好主意。

    关于修订的一些事情:

    • FOUNDATION_EXPORTextern。第一个为 C 和 C++ 编译不同。它基本上意味着extern,但在C++中会添加“C”标志。
    • constsdefinesconsts 是类型安全且尊重范围的。 defines 正好相反。

    【讨论】:

    • 我讨厌将.h .m 用于全局常量。必须将每个变量名写两次是一件很痛苦的事情!
    • 拥有干净、一致、可读的代码的价值是你痛苦的 10 倍。
    • 以下情况我该怎么办?我是错误“初始化元素不是 USER_LIST_URL 的编译时间常数” NSString *const SERVER_URL = @"<a href="/default/index/tourl?u=aHR0cDovL3d3dy5nb29nbGUuY29t" rel="nofollow" target="_blank">google.com</a>"; NSString *const USER_LIST_URL = [NSString stringWithFormat:@"%@/xml/index.cfm",SERVER_URL];
    【解决方案2】:

    我个人更喜欢使用实际的 const 变量而不是定义。

    在我的 MyConstants.m 文件中:

    NSString *const kXYMySiteBaseURL = @"http://api.mysite.com/";
    NSString *const kXYSomeOtherURL = @"http://www.google.com/";
    

    其中 XY 是我的首字母或其他一些“唯一”前缀,以避免与其他常量发生冲突。

    然后我有一个这样的 MyConstants.h 文件:

    extern NSString *const kXYMySitBaseURL;
    extern NSString *const kXYSomeOtherURL;
    

    根据需要访问这些常量的文件数量,我可能会将其包含在预编译的标头中,就像 ColdFusion 在他的回答中建议的那样。

    这是 Apple 在大多数核心框架中定义常量的方式。

    【讨论】:

    • 我知道这可能是一个可以忽略不计的差异 - 但是定义一个常量一次(在您的应用程序的持续时间内存在)VS 使用使用的宏定义实例/局部变量对内存的影响和然后 GC'd on the fly?
    • 您可以在此处阅读developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…,Apple 鼓励您不要使用#define 宏。这就是为什么我比前一个更喜欢这个答案
    • 节省了一点内存。还有一个优点是 isEqual: 或 isEqualToString 甚至不会费心比较字符串,因为它们是相同的指针。
    【解决方案3】:

    我只是创建了一个名为Globals.h 的文件,内容如下:

    #define kBaseURL @"http://api.mysite.com/"
    

    然后使用:

    #import "Globals.h" // at the top
    
    NSString *url = [NSString stringWithFormat:@"%@resources.json",kBaseURL];
    

    【讨论】:

    • 我认为这是最好的方法。
    【解决方案4】:

    我会创建一个单例或使用 AppDelegate 并将常量放在那里。

    【讨论】:

    • 在创建单例之前我会非常仔细地考虑——它们使单元测试变得非常困难,并且通常可以在没有单例的情况下实现相同的目标。使用应用程序委托是一个更好的解决方案,但仍然不理想。许多人会认为将过多的责任放在应用程序委托上是不好的设计。根据 Alex Coplan 的回答,我个人会选择创建一个仅包含常量的全局头文件。
    • @WillPragnell 头文件如何使单元测试比单例更容易?一般来说,单例使单元测试变得困难,但这似乎正是单例大放异彩的地方。
    【解决方案5】:

    是的,全局标头将是一个理想的解决方案。除非计划将其用于管理数据存储等其他事情,否则我不会采用单例模式。全局变量的单例有点矫枉过正。

    【讨论】:

      猜你喜欢
      • 2011-02-09
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多