2011-11-07 75 views
8

我知道这个问题已经被问了好几次了,但是我的是略有不同的。在重复此操作之前,请仔细阅读。 堆栈溢出中有很多帖子说:“就我个人而言,我讨厌MACROS,不要使用那个狗屎”。我读过所有这些,而且我的情况不同。我正在尝试使用#define宏定义软件(iOS应用)中使用的网址。#define或const string *

我同意使用const字符串比#define宏更好。但是,在一个越来越基于REST的API世界中,接受查询参数作为URL的一部分,你怎么仍然可以使用const字符串来表示一个URL的变化?

而不是http://api.myblog.com/posts?entryid=%@ ,继REST原则将有 http://api.blog.com/posts/entries/[entryid]

在前者类型的API服务器,URL是http://api.myblog.com/posts所有条目,他们不会改变。一个常量字符串是可能的。

在后一种类型中,URL随每个条目而变化,我使用一个扩展为像这样的完整URL的宏。

#define GET_ENTRY_URL(__MY_ENTRY_ID__) [NSString stringWithFormat:@"http://api.myblog.com/posts/entries/%@", __MY_ENTRY_ID__]; 

我的方法有没有任何设计缺陷? 想知道您的意见。

谢谢。

回答

4

从编译器的角度来看,#define是一个预处理器指令(请参阅c中的定义,http://en.wikipedia.org/wiki/C_preprocessor)。

在这种情况下,编译器可能会在编译代码之前进行全文替换。

例如: - 如果你定义:

#define GET_ENTRY_URL(__MY_ENTRY_ID__) [NSString stringWithFormat:@"http://api.myblog.com/posts/entries/%@", __MY_ENTRY_ID__]; 

可能GET_ENTRY_URL的每一个事件(X)与被取代[的NSString ...,X]在你的代码。如果Objective-C的实现遵循这一点,则有可能在我们使用宏的任何地方创建实例。

static const/variable似乎是一个更好的方法。

+0

如何传递的静态常量NSString的变量? – Mugunth

+1

你知道你不能,因为它是一个常数。如果API变得更复杂,我会像NSURL一样构造类,可以在里面完成网址构建。也许使用宏还不是至关重要,但是当这段代码到达很多地方时,事情可能会再次出现错误。例如:将所有GET_ENTRY_URL(x)分成两个GET_CODING_ENTRY_URL(x),GET_PERSONAL_ENTRY_URL(x)。 – alvinsj

2

我在应用程序中做的是在必要时为路径内的替换格式代码定义一个基本路径的常量,并为每个特定路径定义一个常量。

NSString const *APIBasePath  = @"http://api.mydomain.com"; 
NSString const *APIEntryPath  = @"/entries/%d"; 
NSString const *APIUpdateEntryPath = @"/entries/%d/update"; 

我再构建在运行时的URL为每个API如下:

- (void)updateEntryNumber:(NSUInteger)entryNumber 
{ 
    NSString *updateEntryPath = [NSString stringWithFormat:APIUpdateEntryPath, entryNumber]; 
    NSString *APIPath = [APIBasePath stringByAppendingPathComponent:updateEntryPath]; 
    // do something 
} 
+0

我刚刚发现'stringByAppendingPathComponent:'只返回一个斜杠,即'http:/ ...',似乎这个方法用于文件路径,而不是url。相反,我使用'stringByAppendingString:'。 :) – Kjuly

相关问题