Objective-C의 상수
Cocoa 응용 프로그램을 개발 중이며 NSString
내 환경 설정에 대한 키 이름을 저장하는 방법으로 constant s를 사용 하고 있습니다.
필요한 경우 키를 쉽게 변경할 수 있기 때문에 이것이 좋은 생각이라는 것을 이해합니다. 또한 전체 '데이터를 논리에서 분리'개념입니다.
어쨌든 전체 응용 프로그램에 대해 이러한 상수를 한 번 정의하는 좋은 방법이 있습니까? 쉽고 지능적인 방법이 있다고 확신하지만 지금은 수업이 사용하는 수업을 재정의합니다.
다음과 같은 헤더 파일을 만들어야합니다.
// Constants.h
FOUNDATION_EXPORT NSString *const MyFirstConstant;
FOUNDATION_EXPORT NSString *const MySecondConstant;
//etc.
( 혼합 C / C ++ 환경이나 다른 플랫폼에서 코드를 사용하지 않을 경우 extern
대신 사용할 수 있습니다. FOUNDATION_EXPORT
)
상수를 사용하는 각 파일이나 프로젝트의 미리 컴파일 된 헤더에이 파일을 포함 할 수 있습니다.
다음과 같은 .m 파일에 이러한 상수를 정의합니다.
// Constants.m
NSString *const MyFirstConstant = @"FirstConstant";
NSString *const MySecondConstant = @"SecondConstant";
Constants.m은 최종 제품에 연결되도록 애플리케이션 / 프레임 워크의 대상에 추가되어야합니다.
#define
'd 상수 대신 문자열 상수를 사용할 때의 장점은 stringInstance == MyFirstConstant
문자열 비교 ( [stringInstance isEqualToString:MyFirstConstant]
) 보다 훨씬 빠르고 읽기 쉬운 IMO 인 포인터 비교 ( )를 사용하여 동등성을 테스트 할 수 있다는 것 입니다.
가장 쉬운 방법:
// Prefs.h
#define PREFS_MY_CONSTANT @"prefs_my_constant"
더 좋은 방법:
// Prefs.h
extern NSString * const PREFS_MY_CONSTANT;
// Prefs.m
NSString * const PREFS_MY_CONSTANT = @"prefs_my_constant";
두 번째 이점 중 하나는 상수 값을 변경해도 전체 프로그램이 다시 빌드되지 않는다는 것입니다.
언급 할 것이 하나 있습니다. 비 전역 상수가 필요한 경우 static
키워드 를 사용해야 합니다.
예
// In your *.m file
static NSString * const kNSStringConst = @"const value";
때문에의 static
키워드,이 CONST는 파일의 외부에 표시되지 않습니다.
@QuinnTaylor에 의한 사소한 수정 : 정적 변수는 컴파일 단위 내에서 볼 수 있습니다 . 일반적으로 이것은 단일 .m 파일 (이 예제에서와 같이)이지만 컴파일 후 링커 오류가 발생하기 때문에 다른 곳에 포함 된 헤더에 선언하면 물릴 수 있습니다.
승인 된 (정확한) 대답은 "이 [Constants.h] 파일을 프로젝트의 미리 컴파일 된 헤더에 포함 할 수 있습니다."라고 말합니다.
초보자로서 추가 설명없이이 작업을 수행하는 데 어려움이있었습니다. 방법은 다음과 같습니다. YourAppNameHere-Prefix.pch 파일 (Xcode에서 미리 컴파일 된 헤더의 기본 이름)에서 Constants.h 를 #ifdef __OBJC__
블록 안에 가져옵니다 .
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "Constants.h"
#endif
또한 Constants.h 및 Constants.m 파일에는 허용 된 답변에 설명 된 내용을 제외하고는 다른 어떤 것도 포함되지 않아야합니다. (인터페이스 또는 구현 없음).
저는 일반적으로 Barry Wark와 Rahul Gupta가 게시 한 방식을 사용하고 있습니다.
하지만 .h 및 .m 파일에서 같은 단어를 반복하는 것을 좋아하지 않습니다. 다음 예제에서 행은 두 파일에서 거의 동일합니다.
// file.h
extern NSString* const MyConst;
//file.m
NSString* const MyConst = @"Lorem ipsum";
따라서 제가 좋아하는 것은 C 전 처리기 기계를 사용하는 것입니다. 예를 들어 설명하겠습니다.
매크로를 정의하는 헤더 파일이 있습니다 STR_CONST(name, value)
.
// StringConsts.h
#ifdef SYNTHESIZE_CONSTS
# define STR_CONST(name, value) NSString* const name = @ value
#else
# define STR_CONST(name, value) extern NSString* const name
#endif
상수를 정의하려는 내 .h / .m 쌍에서 다음을 수행합니다.
// myfile.h
#import <StringConsts.h>
STR_CONST(MyConst, "Lorem Ipsum");
STR_CONST(MyOtherConst, "Hello world");
// myfile.m
#define SYNTHESIZE_CONSTS
#import "myfile.h"
et voila, 나는 .h 파일의 상수에 대한 모든 정보를 가지고 있습니다.
나 자신은 다음과 같은 환경 설정에 사용되는 상수 NSStrings를 선언하는 데 전용 헤더가 있습니다.
extern NSString * const PPRememberMusicList;
extern NSString * const PPLoadMusicAtListLoad;
extern NSString * const PPAfterPlayingMusic;
extern NSString * const PPGotoStartupAfterPlaying;
Then declaring them in the accompanying .m file:
NSString * const PPRememberMusicList = @"Remember Music List";
NSString * const PPLoadMusicAtListLoad = @"Load music when loading list";
NSString * const PPAfterPlayingMusic = @"After playing music";
NSString * const PPGotoStartupAfterPlaying = @"Go to startup pos. after playing";
This approach has served me well.
Edit: Note that this works best if the strings are used in multiple files. If only one file uses it, you can just do #define kNSStringConstant @"Constant NSString"
in the .m file that uses the string.
A slight modification of the suggestion of @Krizz, so that it works properly if the constants header file is to be included in the PCH, which is rather normal. Since the original is imported into the PCH, it won't reload it into the .m
file and thus you get no symbols and the linker is unhappy.
However, the following modification allows it to work. It's a bit convoluted, but it works.
You'll need 3 files, .h
file which has the constant definitions, the .h
file and the .m
file, I'll use ConstantList.h
, Constants.h
and Constants.m
, respectively. the contents of Constants.h
are simply:
// Constants.h
#define STR_CONST(name, value) extern NSString* const name
#include "ConstantList.h"
and the Constants.m
file looks like:
// Constants.m
#ifdef STR_CONST
#undef STR_CONST
#endif
#define STR_CONST(name, value) NSString* const name = @ value
#include "ConstantList.h"
Finally, the ConstantList.h
file has the actual declarations in it and that is all:
// ConstantList.h
STR_CONST(kMyConstant, "Value");
…
A couple of things to note:
I had to redefine the macro in the
.m
file after#undef
ing it for the macro to be used.I also had to use
#include
instead of#import
for this to work properly and avoid the compiler seeing the previously precompiled values.This will require a recompile of your PCH (and probably the entire project) whenever any values are changed, which is not the case if they are separated (and duplicated) as normal.
Hope that is helpful for someone.
// Prefs.h
extern NSString * const RAHUL;
// Prefs.m
NSString * const RAHUL = @"rahul";
As Abizer said, you could put it into the PCH file. Another way that isn't so dirty is to make a include file for all of your keys and then either include that in the file you're using the keys in, or, include it in the PCH. With them in their own include file, that at least gives you one place to look for and define all of these constants.
If you want something like global constants; a quick an dirty way is to put the constant declarations into the pch
file.
Try using a class method:
+(NSString*)theMainTitle
{
return @"Hello World";
}
I use it sometimes.
If you like namespace constant, you can leverage struct, Friday Q&A 2011-08-19: Namespaced Constants and Functions
// in the header
extern const struct MANotifyingArrayNotificationsStruct
{
NSString *didAddObject;
NSString *didChangeObject;
NSString *didRemoveObject;
} MANotifyingArrayNotifications;
// in the implementation
const struct MANotifyingArrayNotificationsStruct MANotifyingArrayNotifications = {
.didAddObject = @"didAddObject",
.didChangeObject = @"didChangeObject",
.didRemoveObject = @"didRemoveObject"
};
I use a singleton class, so that I can mock the class and change the constants if necessary for testing. The constants class looks like this:
#import <Foundation/Foundation.h>
@interface iCode_Framework : NSObject
@property (readonly, nonatomic) unsigned int iBufCapacity;
@property (readonly, nonatomic) unsigned int iPort;
@property (readonly, nonatomic) NSString * urlStr;
@end
#import "iCode_Framework.h"
static iCode_Framework * instance;
@implementation iCode_Framework
@dynamic iBufCapacity;
@dynamic iPort;
@dynamic urlStr;
- (unsigned int)iBufCapacity
{
return 1024u;
};
- (unsigned int)iPort
{
return 1978u;
};
- (NSString *)urlStr
{
return @"localhost";
};
+ (void)initialize
{
if (!instance) {
instance = [[super allocWithZone:NULL] init];
}
}
+ (id)allocWithZone:(NSZone * const)notUsed
{
return instance;
}
@end
And it is used like this (note the use of a shorthand for the constants c - it saves typing [[Constants alloc] init]
every time):
#import "iCode_FrameworkTests.h"
#import "iCode_Framework.h"
static iCode_Framework * c; // Shorthand
@implementation iCode_FrameworkTests
+ (void)initialize
{
c = [[iCode_Framework alloc] init]; // Used like normal class; easy to mock!
}
- (void)testSingleton
{
STAssertNotNil(c, nil);
STAssertEqualObjects(c, [iCode_Framework alloc], nil);
STAssertEquals(c.iBufCapacity, 1024u, nil);
}
@end
If you want to call something like this NSString.newLine;
from objective c, and you want it to be static constant, you can create something like this in swift:
public extension NSString {
@objc public static let newLine = "\n"
}
And you have nice readable constant definition, and available from within a type of your choice while stile bounded to context of type.
참고URL : https://stackoverflow.com/questions/538996/constants-in-objective-c
'Nice programing' 카테고리의 다른 글
최대 요청 길이를 초과했습니다. (0) | 2020.09.27 |
---|---|
Python이 해석되는 경우 .pyc 파일은 무엇입니까? (0) | 2020.09.27 |
치명적인 오류 : Python.h : 해당 파일 또는 디렉터리가 없습니다. (0) | 2020.09.27 |
JavaScript에서 null과 undefined의 차이점은 무엇입니까? (0) | 2020.09.27 |
그룹화 함수 (tapply, by, 집계) 및 * apply 제품군 (0) | 2020.09.27 |