Objective c 其中';iOS应用程序中存储常量的最佳位置是哪里?

Objective c 其中';iOS应用程序中存储常量的最佳位置是哪里?,objective-c,ios,Objective C,Ios,我正在开发一个应用程序,它从JSON API获取资源 所有资源都具有相同的基本URL: http://api.mysite.com/resources.json http://api.mysite.com/other_resources.json 我想存储http://api.mysite.com/string,这样我的所有控制器和模型都可以使用它,在编写资源URL时消除了一些重复 在哪里做这件事最好?-prefix.pch文件 任何建议我都会创建一个singleton或使用AppDelega

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

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

http://api.mysite.com/resources.json
http://api.mysite.com/other_resources.json
我想存储
http://api.mysite.com/
string,这样我的所有控制器和模型都可以使用它,在编写资源URL时消除了一些重复

在哪里做这件事最好?-prefix.pch文件


任何建议我都会创建一个singleton或使用AppDelegate并将常量放在那里。

我只是创建一个名为
Globals.h
的文件,其中包含以下内容:

#define kBaseURL @"http://api.mysite.com/"
然后使用:

#import "Globals.h" // at the top

NSString *url = [NSString stringWithFormat:@"%@resources.json",kBaseURL];

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

将所有常量放在名为“constants.h”的文件中(或您想要的w/e)

编辑:
  • 当我三年前回答这个问题时,我正处于
    #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
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\u导出
    vs
    extern
    。第一个编译C和C++的不同。它基本上是指代码>外部> /COD>,但是在C++中会添加“C”标志。
  • 常量
    vs
    定义
    <代码>常量
是类型安全的,并尊重范围<代码>定义正好相反
是的,全局标题将是理想的解决方案。除非计划将其用于管理数据存储之类的其他事情,否则我不会使用单例模式。对于全球人来说,单身有点过分了

就个人而言,我更喜欢使用实际常量变量,而不是定义

在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在他的回答中建议的那样将其包含在预编译头中


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

在创建单例之前,我会非常仔细地考虑-它们使得单元测试非常困难,通常没有单例测试也可以实现同样的目标。使用AppDelegate是一个更好的解决方案,但仍然不理想。许多人认为把太多的责任放在App委托上是一个糟糕的设计。根据Alex Coplan的回答,我个人会选择创建一个只包含常量的全局头文件。@WillPragnell头文件如何使单元测试比单例测试更容易?一般来说,单例测试会使单元测试变得困难,但这似乎正是单例测试的亮点所在。我认为这是最好的方式。我知道这可能是一个可以忽略不计的区别——但是定义一个常量一次(在你的应用程序持续时间内)对内存有什么影响VS使用已使用的宏定义实例/局部变量,然后动态执行GC?正如您在这里看到的,Apple鼓励您不要使用#定义宏。这就是为什么我喜欢这个答案,而不是前一个答案,因为它节省了一点内存。还有一个优点,例如isEqual:或isEqualToString甚至不会比较字符串,因为它们是同一个指针。我讨厌对全局常量使用
.h.m
。每个变量名必须写两次是一件痛苦的事!拥有干净、一致、可读的代码是你痛苦的10倍。对于以下情况,我应该怎么做?错误“initialize元素不是USER_LIST_URL的编译时常量”
NSString*const SERVER_URL=@;NSString*const USER_LIST_URL=[NSString stringWithFormat:@“%@/xml/index.cfm”,服务器_URL]
extern NSString *const kXYMySitBaseURL;
extern NSString *const kXYSomeOtherURL;