Objective C: Когда назвать self.myObject по сравнению только с вызовом myObject

Здесь самый простой алгоритм , если Вы хотите только отбросить сообщения, когда они прибывают слишком быстро (вместо того, чтобы ставить их в очередь, который имеет смысл, потому что очередь могла бы стать произвольно многочисленной):

rate = 5.0; // unit: messages
per  = 8.0; // unit: seconds
allowance = rate; // unit: messages
last_check = now(); // floating-point, e.g. usec accuracy. Unit: seconds

when (message_received):
  current = now();
  time_passed = current - last_check;
  last_check = current;
  allowance += time_passed * (rate / per);
  if (allowance > rate):
    allowance = rate; // throttle
  if (allowance < 1.0):
    discard_message();
  else:
    forward_message();
    allowance -= 1.0;

нет никаких datastructures, таймеры и т.д. в этом решении, и оно работает чисто:) Для наблюдения этого 'допуск' выращивает на скорости 5/8 единицы в секунды самое большее, т.е. самое большее пять единиц в восемь секунд. Каждое сообщение, которое передается, вычитает одну единицу, таким образом, Вы не можете отправить больше чем пять сообщений в каждые восемь секунд.

Примечание, которое rate должно быть целым числом, т.е. без ненулевой десятичной части или алгоритма, не будет работать правильно (фактический уровень не будет rate/per). Например, rate=0.5; per=1.0; не работает, потому что allowance никогда не будет расти до 1,0. Но rate=1.0; per=2.0; хорошо работает.

5
задан User97693321 30 July 2012 в 03:37
поделиться

5 ответов

Если вы просто обращаетесь к ним, нет особых причин использовать self.member . Если вы выполняете присваивание, хорошо, если вы делаете больше, чем простой параметр @property (assign) - например, сохранять, копировать и т. Д., Чтобы сэкономить на коде, который вы письмо. Пример:

myObject = anotherObject;
self.myObject = anotherObject;

Второй вариант гарантирует, что вы действительно назначаете объект так, как хотите (получение копии, увеличение счетчика сохранения и т. Д.). Он не отличается от [self setMyObject: anotherObject] .

8
ответ дан 18 December 2019 в 14:49
поделиться

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

Если вы используете синтезированные акцепторы, их вызов просто добавляет (возможно) ненужные накладные расходы. Если аксессоры имеют более сложную реализацию, вы просто скрываете цель кода.

Наконец, некоторые люди, которые плохо знакомы с Objective-C, используют себя. синтаксис свойства и синтезированные методы доступа, чтобы попытаться избежать понимания управления памятью Какао. Вам действительно нужно узнать, как это работает, поэтому попытки избежать этого контрпродуктивны.

1
ответ дан 18 December 2019 в 14:49
поделиться

Хм, я не могу сказать, что согласен с Марком или Синдером 6.

Что ж, согласен в первой части. :-) self.foo вызывает метод -foo . Обычный foo обращается к foo ivar.

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

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

3
ответ дан 18 December 2019 в 14:49
поделиться

Если вы используете Core Data, вы должны всегда использовать аксессоры, поскольку некоторые свойства могут не загружаться из постоянного хранилища до тех пор, пока они не понадобятся. (В любом случае, предполагая, что вы используете хранилище SQLite.)

Если вы не используете Core Data, вы можете просто использовать myObject напрямую, если вы только читаете значение. Если вы изменяете значение myObject , вам необходимо использовать средства доступа, чтобы убедиться, что любые другие объекты, наблюдающие значение этого свойства, должным образом уведомлены. Другими словами:

// Not changing the value of myObject, so no accessor needed
[someMutableArray addObject:myObject];  

// Changes the value, so you need to use the accessor
self.myObject = newObject;     
[self setMyObject:newObject];  // Exactly identical to the previous line.

В общем, накладных расходов очень мало; Я предпочитаю всегда использовать аксессоры даже внутри одного объекта. (Конечно, есть аргументы в пользу их использования в инициализаторах, но это отдельный вопрос.)

1
ответ дан 18 December 2019 в 14:49
поделиться

Здесь нет кратких ответов. Однако помните, что преждевременная оптимизация - это плохо. В Cocoa на Mac или на iPhone использование средств доступа / свойств должно быть KVO-совместимым. Соответствие KVO необходимо для автоматической работы Core Data и Cocoa Bindings. В Core Data необходимо обеспечить KVO не только при изменении свойств, но и при доступе к ним.

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

Существует ряд различных шаблонов управления памятью. Все нерабочие гарантируют, что объект, возвращаемый средством доступа, выживет как минимум до конца текущей области автозапуска. Это означает, что либо объект явно сохраняется и автоматически освобождается в текущей области автозапуска. Метод, рекомендованный Apple, делает это явно в получателе:

- (id)foo {return [[foo retain] autorelease]; }
- (void)setFoo:(id)aFoo {
  if(! [aFoo isEqual:foo]) {
     [foo release];
     foo = [aFoo retain];
  }
}

Подразумевается, что ' s шаблон, которому они следуют в своих синтезированных аксессуарах. Лично я предпочитаю автоматически выпускать в установщике:

- (id)foo {return foo;}
- (void)setFoo:(id)aFoo {
  [foo autorelease];
  foo = [aFoo retain];
}

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

Это означает, что использование средств доступа / свойств придаст вам уверенности что ваши объекты будут существовать столько, сколько вам нужно, без какой-либо другой части кода, высвобождающей их из-под вас.

Последняя и лучшая причина всегда использовать аксессоры / свойства состоит в том, что для каждого свойства делается на одно допущение меньше: для этого свойства существует базовый ivar, и у него то же имя (я предполагаю, что это два предположения). Возможно, в будущем вы захотите заменить ivar производным аксессуаром. Обозначение свойств по-прежнему будет работать. Возможно, вы захотите переименовать ивар; собственность по-прежнему будет работать. К счастью, на рефакторинг в Xcode обычно можно положиться, но зачем вообще беспокоиться?

Смысл объектно-ориентированного программирования заключается в использовании интерфейсов, определенных в классе. У класса нет веской причины (хотя существует множество предвзятых и рационализированных причин) игнорировать свой собственный интерфейс. Каждый метод, кроме самих средств доступа, в общем случае должен относитесь к объекту как к священному, а его внутреннее состояние как к частному. Пишите каждый метод, как если бы он был в категории или в подклассе, и относитесь к ivars как к частному состоянию, если конкретный дизайн не требует прямого указания от вас. Есть множество веских причин для прямого доступа к ivars, но они определяются в каждом конкретном случае.

0
ответ дан 18 December 2019 в 14:49
поделиться