Константы в Objective-C - PullRequest
       77

Константы в Objective-C

993 голосов
/ 12 февраля 2009

Я разрабатываю приложение Какао и использую константы NSString s как способы хранения имен ключей для своих предпочтений.

Я понимаю, что это хорошая идея, потому что она позволяет легко менять ключи при необходимости. Плюс, это целое понятие «отделяй свои данные от своей логики».

В любом случае, есть ли хороший способ сделать эти константы определенными один раз для всего приложения? Я уверен, что есть простой и умный способ, но сейчас мои уроки просто переопределяют те, которые они используют.

Ответы [ 14 ]

8 голосов
/ 25 июля 2015

Если вам нравится константа пространства имен, вы можете использовать struct, Friday Q & A 2011-08-19: Константы и функции в пространстве имен

// 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"
};
8 голосов
/ 06 декабря 2009

Попробуйте использовать метод класса:

+(NSString*)theMainTitle
{
    return @"Hello World";
}

Я использую это иногда.

7 голосов
/ 16 июля 2012

Я использую одноэлементный класс, так что я могу смоделировать класс и изменить константы, если это необходимо для тестирования. Класс констант выглядит так:

#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

И он используется следующим образом (обратите внимание на использование сокращения для констант c - он экономит при наборе [[Constants alloc] init] каждый раз):

#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
0 голосов
/ 21 января 2019

Если вы хотите вызвать что-то подобное NSString.newLine; из цели c и хотите, чтобы оно было статической константой, вы можете создать что-то подобное в swift:

public extension NSString {
    @objc public static let newLine = "\n"
}

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

...