Он работает как быстрыми 3, так и 4
@IBAction func NextView(_ sender: UIButton) {
let newVC = self.storyboard?.instantiateViewControllerWithIdentifier(withIdentifier: "NewVC") as! NewViewController
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionPush
transition.subtype = kCAGravityLeft
//instead "kCAGravityLeft" try with different transition subtypes
self.navigationController?.view.layer.add(transition, forKey: kCATransition)
self.navigationController?.pushViewController(newVC, animated: false)
}
Единственная вещь, которую я вижу, состоит в том, что Ваше принуждение копии списка Вы возвращаетесь. Было бы более эффективно сделать что-то как:
void DoSomething(const std::vector<SomeType>& in, std::vector<SomeType>& out)
{
...
// no need to return anything, just modify out
}
, поскольку Вы передаете в списке, который Вы хотите возвратить, Вы избегаете дополнительной копии.
Редактирование: Это - старый ответ. Если можно использовать современный компилятор C++ с семантикой перемещения, Вы не должны волноваться об этом. Конечно, этот ответ все еще применяется, если объект, который Вы возвращаете, НЕ имеет семантики перемещения.
Если бы Вам действительно нужен новый список, я просто возвратил бы его. Оптимизация возвращаемого значения не будет заботиться ни о каких бесполезных копиях в большинстве случаев, и Ваш код остается очень четким.
Однако беря списки и возвращая другие списки действительно программирование Python в C++.
А, для C++, более подходящая парадигма должен был бы создать функции, которые берут диапазон итераторов и изменяют базовый набор.
, например,
void DoSomething(iterator const & from, iterator const & to);
(с итератором, возможно являющимся шаблоном, в зависимости от Ваших потребностей)
, операции Объединения в цепочку являются затем вопросом обращения к последовательным методам, начинаются (), конец (). Если бы Вы не хотите изменять вход, Вы сделали бы копию сами сначала.
std::vector theOutput(inputVector);
это все прибывает из C++, "не платят за то, что Вам не нужна" философия, Вы только создали бы копии, где Вы на самом деле хотите сохранить оригиналы.
Я использовал бы универсальный подход:
template <typename InIt, typename OutIt>
void DoMagic(InIt first, InIt last, OutIt out)
{
for(; first != last; ++first) {
if(IsCorrectIngredient(*first)) {
*out = DoMoreMagic(*first);
++out;
}
}
}
Теперь можно назвать его
std::vector<MagicIngredients> ingredients;
std::vector<MagicResults> result;
DoMagic(ingredients.begin(), ingredients.end(), std::back_inserter(results));
, можно легко изменить контейнеры, используемые, не изменяя используемый алгоритм, также эффективно, чтобы не было никаких издержек в возврате контейнеров.
Если Вы хотите быть действительно хардкором, Вы могли бы использовать повышение:: кортеж .
tuple<int, int, double> add_multiply_divide(int a, int b) {
return make_tuple(a+b, a*b, double(a)/double(b));
}
, Но так как это кажется, все Ваши объекты имеют единственный, неполиморфный тип, затем станд.:: вектор - все хорошо и прекрасный. Если бы Ваши типы были полиморфными (наследованные классы базового класса) затем, то Вам был бы нужен вектор указателей, и необходимо будет не забыть удалять все выделенные объекты перед выбрасыванием вектора.
Используя станд.:: вектор предпочтительно путь во многих ситуациях. Его гарантируемый для использования последовательной памяти и для этого приятен для кэша L1.
необходимо знать о том, какой happends, когда тип возврата является станд.:: вектор. То, что происходит под капотом, то, что станд.:: вектор рекурсивный скопированный, поэтому если конструктор копии SomeType является дорогим, "оператор возврата" может быть долгой и трудоемкой операцией.
, Если Вы ищете и вставляете много в свой список, Вы могли бы посмотреть на станд.:: набор для получения логарифмической временной сложности вместо линейного. (станд.:: вставка векторов является постоянной, пока ее способность не превышена).
Вы говорите, что у Вас есть много "функций канала"... походит на превосходный сценарий для станд.:: преобразовать.
Другая проблема с возвратом списка объектов (настроенный против работы над одним или двумя списками на месте, как BigSandwich указал), состоит в том, если Ваши объекты будут иметь конструкторов копии комплекса, то они будут, призвал к каждому элементу в контейнере.
, Если у Вас есть 1 000 объектов каждая ссылка на ломоть памяти, и они копируют ту память на Объекте a, b; a=b; это - 1000 memcopys для Вас, только для возврата их содержавшийся в контейнере. Если Вы все еще хотите возвратить контейнер непосредственно, думайте об указателях в этом случае.
Это работает очень простое.
list<int> foo(void)
{
list<int> l;
// do something
return l;
}
Теперь получающие данные:
list<int> lst=foo();
полностью оптимально, потому что компилятор знает для оптимизации конструктора LST хорошо. и не вызвал бы копии.
Другой метод, более портативный:
list<int> lst;
// do anything you want with list
lst.swap(foo());
, Что происходит: нечто уже оптимизировало, таким образом, нет никакой проблемы для возвращения значения. Когда Вы называете подкачку Вами установленное значение LST к новому, и таким образом не копируете его. Теперь старое значение LST "подкачано" и разрушено.
Это - эффективный способ сделать задание.