В Objective C у меня есть простой блок кода, который увеличивает счетчик каждый раз, когда кнопка нажата. Мои журналы, и даже обновляют к интерфейсу, показывают инкремент 4 вместо одного. Это - просто проблема дисплея с моим форматированием (я использую %d), или что-то еще, что я пропускаю? Мое предположение находится с "%d", но я плохо знаком с Objective C и не уверен. (Отметьте, я также попробовал "счетчик + = 1"; с тем же результатом.
int counterValue = 0;
NSLog(@"Count at init: %d",counterValue);
...
-(IBAction)pushButton {
NSLog(@"Count (Pre-Push) = %d",counterValue);
counterValue++;
NSLog(@"Count (Post-Push) = %d",counterValue);
}
Вывод следующие:
2010-02-20 18:39:39.125 My App[37536:207] Count at init: 0
2010-02-20 18:39:39.845 My App[37536:207] Count (Pre-Push) = 0
2010-02-20 18:39:39.846 My App[37536:207] Count (Post-Push) = 4
2010-02-20 18:39:40.165 My App[37536:207] Count (Pre-Push) = 4
2010-02-20 18:39:40.166 My App[37536:207] Count (Post-Push) = 8
2010-02-20 18:39:40.727 My App[37536:207] Count (Pre-Push) = 8
2010-02-20 18:39:40.728 My App[37536:207] Count (Post-Push) = 12
Я бы не стал этого делать. Это нарушает инкапсуляцию и меняет контракт того, что ваш класс должен делать, не зная об этом реализаторов.
Если вы должны это сделать, однако, лучший способ - вызвать
class.getMethod("myMethod").getDeclaringClass();
Если возвращенный класс является вашим собственным, то он не переопределен; если это что-то другое, этот подкласс его переопределяет. Да, это отражение, но все еще довольно дешево.
Мне нравится ваш подход защищенного метода, хотя. Это выглядит примерно так:
public class ExpensiveStrategy {
public void expensiveMethod() {
// ...
if (employOptimization()) {
// take a shortcut
}
}
protected boolean employOptimization() {
return false;
}
}
public class TargetedStrategy extends ExpensiveStrategy {
@Override
protected boolean employOptimization() {
return true; // Now we can shortcut ExpensiveStrategy.
}
}
-121--2303367- Для этого нет прямого метода. Я написал этот патч обезьяны для ActiveRecord:: Base
.
Это будет работать для любого класса.
class ActiveRecord::Base
def self.all_polymorphic_types(name)
@poly_hash ||= {}.tap do |hash|
Dir.glob(File.join(Rails.root, "app", "models", "**", "*.rb")).each do |file|
klass = File.basename(file, ".rb").camelize.constantize rescue nil
next unless klass.ancestors.include?(ActiveRecord::Base)
klass.
reflect_on_all_associations(:has_many).
select{ |r| r.options[:as] }.
each do |reflection|
(hash[reflection.options[:as]] ||= []) << klass
end
end
end
@poly_hash[name.to_sym]
end
end
Теперь вы можете сделать следующее:
Assignable.all_polymorphic_types(:assignable).map(&:to_s)
# returns ['Project', 'Event', 'Group']
-121--3133390- Код, который вы показываете, не должен этого делать. Я сделал быструю программу, чтобы doublecheck, и я получаю ожидаемые результаты:
2010-02-22 17:04:35.787 app[68267:a0f] Count (Pre-Push) = 0
2010-02-22 17:04:35.790 app[68267:a0f] Count (Post-Push) = 1
2010-02-22 17:04:35.923 app[68267:a0f] Count (Pre-Push) = 1
2010-02-22 17:04:35.924 app[68267:a0f] Count (Post-Push) = 2
Я думаю, что вы затенены counterValue
с другой переменной типа int *
, которая делает +
приращение на sizeof (int)
, а не на 1.