Подтвердить что ты не робот

Как объявить константы NSString для перехода в NSNotificationCenter

У меня есть следующее в моем файле .h:

#ifndef _BALANCE_NOTIFICATION
#define _BALANCE NOTIFICATION
const NSString *BalanceUpdateNotification
#endif

и следующее в моем файле .m:

const NSString *BalanceUpdateNotification = @"BalanceUpdateNotification";

Я использую это со следующими кодами:

[[NSNotificationCenter defaultCenter]
    addObserver:self
    selector:@selector(updateBalance:)
    name:BalanceUpdateNotification
    object:nil];

и

[[NSNotificatoinCenter defaultCenter]
    postNotificationName:BalanceUpdateNotification
    object:self userInfo:nil];

Что работает, но это дает мне предупреждение:

Passing argument 1 of 'postNotificationName:object:userInfo' discards qualifiers from pointer target type

Итак, я могу применить его к (NSString *), но мне интересно, как правильно это сделать.

4b9b3361

Ответ 1

NSStrings являются неизменяемыми, поэтому объявление a const NSString * будет избыточным; просто используйте NSString *.

Если то, что вы пытаетесь сделать, это объявить, что сам указатель не может измениться, это будет:

   NSString * const BalanceUpdateNotification = @"BalanceUpdateNotification";

См. также Константы в Objective-C

Ответ 2

Обычно вы объявляете переменную как extern в заголовке. Самый идиоматический способ выглядит следующим образом:

Заголовок

#ifndef __HEADER_H__
#define __HEADER_H__

extern NSString * const BalanceUpdateNotification;

#endif

Источник

#include "header.h"

NSString * const BalanceUpdateNotification = @"BalanceUpdateNotification";

extern сообщает компилятору, что что-то типа NSString * const по имени BalanceUpdateNotification существует где-то. Он может быть в исходном файле, который включает заголовок, но, возможно, нет. Это не задача компилятора, чтобы убедиться, что она существует, только потому, что вы используете ее соответствующим образом в соответствии с тем, как вы ее набрали. Задача компоновщика состоит в том, чтобы убедиться, что BalanceUpdateNotification действительно определен где-то и только один раз.

Помещение const после * означает, что вы не можете переназначить BalanceUpdateNotification, чтобы указать на другой NSString.

Ответ 3

Я не вижу причин не использовать постоянный литерал с директивой препроцессора. #import выполняет функцию включения охранников, поэтому вы можете просто сказать

#define AutomaticallyResumeDownloads @"AutomaticallyResumeDownloads"

а затем #import заголовок, содержащий это определение, где бы он ни понадобился.

Ответ 4

Обычно константы не изменяются. С другой стороны, можно было бы объявить их как externs в файле заголовка. Это (немного), потому что, когда вы говорите const NSString *string, вы сообщаете компилятору, что память, на которую указывает строка, не изменится - это не полезно и не обязательно верно, поскольку мы не можем контролировать, как Классы apple управляют переменными состояния. (Хотя NSStrings, объявленные во время выполнения, помещаются в текстовый сегмент, функциональность может меняться в разных версиях или что-то в этом роде.) Если вы действительно хотели использовать const, о котором я по-прежнему советую, он должен быть NSString * const string, что предотвратит использование указателя изменен, чтобы указать на другое место памяти (которое не будет делать иначе);

Ответ 5

Это рабочее решение для объявления имени NSString для наблюдателей.

static NSString *const MyCustomNotificationName = @"MyCustomNotificationName";

Ответ 6

У Apple есть рекомендация их собственной документации, где помимо прочего используется макрос APPKIT_EXTERN вместо extern. В сочетании с содержимым файла заголовка по умолчанию, созданного в Xcode, это полная реализация:

Constants.h:

#import <Cocoa/Cocoa.h>

#ifndef Constants_h
#define Constants_h

APPKIT_EXTERN NSString *MyConstantName;

#endif

Constants.m:

#import "Constants.h"

NSString *MyConstantName = @"MyConstantValue";

Я думаю, что приведенное выше является более или менее стандартным способом достижения строковых констант, согласно Apple.