C++ 使用#define替换代码

C++ 使用#define替换代码,c++,ios,objective-c,c,C++,Ios,Objective C,C,在我的iOS应用程序中有一大堆代码,我必须在每个视图中使用这些代码——不能在函数/方法中使用它们——因此我想知道是否有任何方法可以使用#在需要的地方定义和使用它的标识符。下面是示例代码 我想用#deinfe identifer替换的代码 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_gotECSlidingVi

在我的iOS应用程序中有一大堆代码,我必须在每个视图中使用这些代码——不能在函数/方法中使用它们——因此我想知道是否有任何方法可以使用#在需要的地方定义和使用它的标识符。下面是示例代码

我想用#deinfe identifer替换的代码

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(_gotECSlidingViewAnchorRightOrRightrNotification) 
                                             name:ECSlidingViewTopDidAnchorLeft 
                                           object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(_gotECSlidingViewAnchorRightOrRightrNotification) 
                                             name:ECSlidingViewTopDidAnchorRight 
                                           object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(_gotECSlidingViewTopDidResetNotification)
                                             name:ECSlidingViewTopDidReset 
                                           object:nil];

因此,我想知道如何定义它并在ViewDidLoad方法中使用它?

如果代码应该与此完全相同,那么应该这样做。否则,您可以将参数放入
#define
以更改有关它的某些内容

#define identifier do{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_gotECSlidingViewAnchorRightOrRightrNotification) name:ECSlidingViewTopDidAnchorLeft  object:nil];\
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_gotECSlidingViewAnchorRightOrRightrNotification) name:ECSlidingViewTopDidAnchorRight object:nil];\
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_gotECSlidingViewTopDidResetNotification) name:ECSlidingViewTopDidReset object:nil];\
} while (0);
您可以使用以下选项:

将\置于每行末尾的空格后,这将阻止编译器检查新行或按enter键。这使得代码可读。然后,您可以在方法中的任何位置使用MY_通知

#define MY_NOTIFICATIONS [[NSNotificationCenter defaultCenter] addObserver:self \
selector:@selector(_gotECSlidingViewAnchorRightOrRightrNotification) \
name:ECSlidingViewTopDidAnchorLeft \
object:nil]; \
\
[[NSNotificationCenter defaultCenter] addObserver:self \
                                         selector:@selector (_gotECSlidingViewAnchorRightOrRightrNotification) \
                                             name:ECSlidingViewTopDidAnchorRight \
                                           object:nil]; \
\
[[NSNotificationCenter defaultCenter] addObserver:self \
                                         selector:@selector(_gotECSlidingViewTopDidResetNotification) \
                                             name:ECSlidingViewTopDidReset \
                                           object:nil]; \

<>这并不能直接回答你的问题,但是作为一个处理预处理器的许多头痛的老C++程序员,我建议不要用这个定义。 有几个选择

  • 使用两个选择器定义基类(从UIViewController派生)。可以在派生类中重写选择器

    @接口YourBaseCass:UIViewController

    • (void)viewDidLoad;//将您的addobserver逻辑放在这里
    • (无效)_gotecslidingviewAnchorright或RightNotification
    • (无效)_gotECSlidingViewTopDidResetNotification
    @结束

    @基于cass的实现

    - (void)viewDidLoad //make sure you call me from the derived class
    {
        [super viewDidLoad]
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(_gotECSlidingViewAnchorRightOrRightrNotification)
                                                     name:ECSlidingViewTopDidAnchorLeft
                                                   object:nil];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(_gotECSlidingViewAnchorRightOrRightrNotification)
                                                     name:ECSlidingViewTopDidAnchorRight
                                                   object:nil];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(_gotECSlidingViewTopDidResetNotification)
                                                     name:ECSlidingViewTopDidReset
                                                   object:nil];
    }
    
    @结束

  • 将您的功能放在全局静态方法中(如果子类化不是您的事情)。这将更容易调试

    • (void)addObserversForbject:(id)对象{ [[NSNotificationCenter defaultCenter]添加观察者:对象 选择器:@selector(_GotecSlidingViewAnchorRightorRightNotification) 名称:ECSlidingViewTopDidAnchorLeft 对象:无]

      [[NSNotificationCenter defaultCenter] addObserver:object
                                               selector:@selector(_gotECSlidingViewAnchorRightOrRightrNotification)
                                                   name:ECSlidingViewTopDidAnchorRight
                                                 object:nil];
      
      [[NSNotificationCenter defaultCenter] addObserver:object
                                               selector:@selector(_gotECSlidingViewTopDidResetNotification)
                                                   name:ECSlidingViewTopDidReset
                                                 object:nil];
      
      }


  • 不要依靠预处理器。这是一种糟糕的风格,常常会导致微妙的混乱。你仍然需要在所有这些文件中包含宏

    而是定义一个类来处理通知

    @interface ECSReceptionist
          - (id) initFor: (id) observer;
    @end
    
    对于一个类来说,这似乎有点轻量级,但您可以在以后赋予它职责。例如,接待员也可以自己注册接收通知,并自主处理一些日常琐事

    避免使用预处理器:

    • 让你的意图更清晰
    • 避免微妙的语法错误,保持理智
    • 使调试更加容易
    • 提供了进一步重构的机会
    • 为单元测试提供了一个测试挂钩

    你想要三合一的定义还是三种不同的定义?@AnoopVaidya-一合一。为什么不能在函数或方法中使用它?@Simon-好问题。这并不是说我不能定义这个函数,而是在每个文件中都会重复相同的函数——这很糟糕——然后有相应的方法来处理这些通知。只是想减少最大代码。您不能将函数放在#define所在的位置吗?据我所知,#defines有时有点棘手,所以我建议使用函数来代替它(虽然,我使用C++已经很久了)。do-while确保它可以在单行if语句等(at)中使用Fonix的评论:难道你不能在表达式周围加上花括号来做同样的事情吗?出于某种原因,我记得它们是一个问题,但现在想不起来了。也许没有,但do-while对meEven一直有效,{and}将充当块,不需要循环或块。你可以简单地在一行中使用全部,就像我在答案中所做的那样。你的答案在代码中仍然被视为3行,如果你在一行中使用它,它可能会破坏一些东西,例如if语句或for循环等。在这种情况下可能不会这样使用,但这是一个很好的实践。(如果您注意到我还必须使用的话)很抱歉代码格式不好。。。我似乎无法使不同的区域正确排列。