2013-05-28 3 views
3

Все, что я хочу сделать, это сделать класс утилиты для моего приложения (захвата потока), которое захватывает настройки с моего сайта. Я хочу назвать это из других файлов как простой [RemoteConfig updateSettings];Неправильная практика использования C-подобных статических переменных в Objective-C?

Моя цель - использовать эту удаленную конфигурационную утилиту, не создавая объект для каждой ситуации, когда я беру удаленные настройки.

Информация о переменных и методах static/class в Objective C является туманной и очень упрямой, поэтому после большого количества экспериментов я получил это для работы. Но это выглядит забавно, что заставляет меня думать, что что-то неверно.

RemoteConfig.h просто объявляет + (недействительными) updateSettings метод.

Это мой RemoteConfig.m:

#import "RemoteConfig.h" 

static NSMutableData* _configData; 
static NSString* url = @"http://local.namehidden.com:90/json.html"; 
static int try; 

@implementation RemoteConfig 

+(void) updateSettings 
{ 
    NSString *identifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString]; 

    //Create URL request 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] 
                  cachePolicy: NSURLRequestReloadIgnoringCacheData 
                 timeoutInterval: 10]; 

    [request setHTTPMethod: @"POST"]; 
    NSString *post = [NSString stringWithFormat:@"id=%@", identifier]; 
    NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding]; 
    [request setHTTPBody:postData]; 

    NSURLConnection* connection = [NSURLConnection connectionWithRequest:request 
                   delegate:self]; 
    [connection start]; 
} 

///////////////////////////// DELEGATE METHODS /////////////////////////////////// 

+(void)connection:(NSConnection*)conn didReceiveResponse:(NSURLResponse*)response 
{ 
     if (_configData == NULL) { 
     _configData = [[NSMutableData alloc] init]; 
    } 
    [_configData setLength:0]; 
    NSLog(@"didReceiveResponse: responseData length:(%d)", _configData.length); 
} 

/// and so on... 

Он выглядит напуганным, помещая переменные C-стиля над реализацией @ интерфейс/@. Многие говорят, что пытаются использовать свойства, некоторые говорят, что это метод статического метода singleton, я видел небольшую библиотеку, которая обрабатывает одиночные игры, но это было самое простое решение, которое я нашел.

Мой вопросы-

  • Является ли это пословице плохо?
  • Какие у этого ограничения есть?
  • Каковы альтернативы, и что лучше?
+2

Не «пословично плохой», но уродливый и небезопасный. –

+0

Я понял, что это вызовет беспорядок с потоками. Что имеет такой же эффект, но обеспечивает безопасность резьбы? – user

+0

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

ответ

4

Это пословицно плохо? Какие существуют ограничения?

Глобальные переменные, как правило, накладывают определенный набор ограничений:

  • они часто не чистят свои ресурсы надлежащим образом
  • не являются поточно (например, можно использовать от одной нити или может ввести состояние на резьбу)
  • Возможно, они не обязательно безопасны для гнездования
  • они могут бороться с некоторыми из этих проблем путем сериализации запросов - введения чрезмерной подвески и блокировки.
  • они становятся очень трудно «продлить» безопасно (т.е. добавление глобальных переменных делает его более хрупким)
  • их трудно проверить, и может привести к ошибкам, которые очень трудно воспроизвести

Каковы альтернативы, и что лучше?

Просто переместите эти переменные на ivars и создайте экземпляры класса, а не полагайтесь на глобальное состояние. Затем вы можете расширять и абстрагироваться таким образом, чтобы не повлиять на ваших клиентов значительно.

Обратите внимание, что static NSString* const url = @"http://local.namehidden.com:90/json.html"; не будет изменяемой переменной (добавлено const). Так что это всего лишь _configData и try, которые должны быть иварами.

+0

Но все дело в том, чтобы сделать утилиту, которая не требует создания экземпляра нового объекта каждый раз, когда я хочу просто захватить настройки из интерфейса JSON. – user

+1

Не бойтесь объектов. Или используйте синглтон. – Wain

+1

@user, создающий объект objc, является тривиальным в подавляющем большинстве контекстов, например. многие объекты создаются и уничтожаются при манипулировании строками и создании типов коллекций. если вы хотите минимизировать сетевые запросы, вы можете передать один объект, успешно выполнивший запрос. некоторые люди не против работать с глобалами - некоторые находят их болью. я писал objc в течение 10 лет. я уверяю вас, что реальные программы могут быть разработаны без внедрения глобальных переменных или синглтонов (они существуют в рамках). лично, я нахожу это намного проще. – justin

0

Использование таких статических переменных, как это, не менее безопасно, чем использование Singleton. Вы по-прежнему будете иметь те же проблемы с безопасностью потоков, например. Синглтон, конечно же, легче размахивать, так что это может принести пользу Синглтону.

В обоих случаях вы вводите глобальное изменчивое состояние (глобальное неизменяемое состояние является непроблематичным). Насколько проблематично это зависит от того, где в иерархии вызовов эти переменные существуют. Если большая часть вашего кода построена поверх некоторых функций, которые меняют свой результат на основе некоторого глобального изменяемого состояния, тогда это затрудняет тестирование и анализ вашего кода.

Так что, если вы ввести глобальное изменяемое состояние, попробуйте либо:

  1. Место имеет высокими, как это возможно в ваших отводках. Значение как можно меньше другого кода должно зависеть от этого кода.

  2. Удостоверьтесь, что изменения состояния не меняют выход функций с его помощью. Например. глобальное изменяемое состояние, которое просто кэшируется, может работать.

  3. Если общий код вашей программы невелик, вы можете использовать глобальное состояние, так как существует небольшая разница между глобальными переменными в 500-строчной программе и переменными-членами в классе 500 строк.

Смежные вопросы