Swift 4 решение, которое работает для меня, чтобы получить URL последнего изображения в Photo Library:
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
let fetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions).lastObject
PHImageManager().requestAVAsset(forVideo: fetchResult!, options: nil, resultHandler { (avurlAsset, _, _) in
if let newObj = avurlAsset as? AVURLAsset {
print(newObj.url)
}
})
Надеюсь, что это поможет!
Я не думаю, что дело в вычислительной производительности в большей степени, чем в увеличении выразительной силы языка.
Преимущество состоит в том, что является наиболее важным при написании компьютерных программ: более простой для понимания код . Мне не известны какие-либо соображения по поводу производительности.
C ++ в определенной степени позволяет выполнять Функциональное программирование . Подумайте об этом:
std::for_each( begin, end, doer );
Проблема в том, что функция (объект) doer
operator ()
функционального объекта) std :: for_each
call Лямбда-выражения значительно улучшают все эти ( а может еще что-то забыл).
Само по себе повышения производительности нет, но потребность в лямбда-выражении возникла как следствие широкого распространения STL и его дизайнерских идей.
В частности, алгоритмы STL часто используют функторы. Без лямбда эти функторы должны быть заранее объявлены для использования. Лямбда-выражения позволяют иметь «анонимные» функторы на месте.
Это важно, потому что есть много ситуаций, в которых вам нужно использовать функтор только один раз, и вы не хотите давать ему имя по двум причинам: вы не хотите загрязнять пространство имен и в в этих конкретных случаях имя, которое вы даете, либо расплывчатое, либо очень длинное.
Я, например, много использую STL, но без C ++ 0x я использую гораздо больше циклов for (), чем алгоритм for_each () и его собратья. Это потому, что если бы я использовал вместо этого for_each (), мне нужно было бы получить код из цикла и объявить для него функтор. Кроме того, все локальные переменные перед циклом не будут доступны, поэтому мне нужно написать дополнительный код, чтобы передать их в качестве параметров конструктору функтора или другому эквиваленту. Как следствие, я стараюсь не использовать for_each (), если нет сильной мотивации, иначе код был бы длиннее и труднее читался.
Это плохо, потому что хорошо известно, что использование for_each () и подобных алгоритмов дает гораздо больше возможностей компилятору и библиотеке для оптимизации, включая автоматический параллелизм. Таким образом, косвенно лямбда будет способствовать более эффективному коду.
IMO, самое важное в лямбдах - это то, что они удерживают связанный код рядом друг с другом. Если у вас есть такой код:
std::for_each(begin, end, unknown_function);
Вам нужно перейти к unknown_function
, чтобы понять, что делает код. Но с помощью лямбды логика может быть собрана вместе.
Лямбды являются синтаксическим сахаром для классов функторов, поэтому нет, вычислительной выгоды нет. Что касается мотивации, возможно, любой другой из дюжины или около того популярных языков, в которых есть лямбда-выражения?
Можно утверждать, что это помогает в удобочитаемости кода (если ваш функтор объявлен встроенным там, где он используется).
Хотя я считаю другие части C++0x более важными, лямбды - это больше, чем просто "синтаксический сахар" для объектов функций в стиле C++98, потому что они могут захватывать контексты, и они делают это по имени, а затем они могут брать эти контексты в другом месте и выполнять. Это нечто новое, а не то, что "компилируется быстрее/медленнее".
#include <iostream>
#include <vector>
#include <functional>
void something_else(std::function<void()> f)
{
f(); // A closure! I wonder if we can write in CPS now...
}
int main()
{
std::vector<int> v(10,0);
std::function<void ()> f = [&](){ std::cout << v.size() << std::endl; };
something_else(f);
}
Что ж, сравните это:
int main () {
std::vector<int> x = {2, 3, 5, 7, 11, 13, 17, 19};
int center = 10;
std::sort(x.begin(), x.end(), [=](int x, int y) {
return abs(x - center) < abs(y - center);
});
std::for_each(x.begin(), x.end(), [](int v) {
printf("%d\n", v);
});
return 0;
}
с этим:
// why enforce this to be defined nonlocally?
void printer(int v) {
printf("%d\n", v);
}
int main () {
std::vector<int> x = {2, 3, 5, 7, 11, 13, 17, 19};
// why enforce we to define a whole struct just need to maintain a state?
struct {
int center;
bool operator()(int x, int y) const {
return abs(x - center) < abs(y - center);
}
} comp = {10};
std::sort(x.begin(), x.end(), comp);
std::for_each(x.begin(), x.end(), printer);
return 0;
}
"изящная фишка разработчиков, открытая для злоупотребления бедными кодерами, пытающимися выглядеть крутыми?"... как бы вы это ни называли, это делает код намного более читабельным и удобным для сопровождения. Это не увеличивает производительность.
Чаще всего программист выполняет итерации над рядом элементов (поиск элемента, накопление элементов, сортировка элементов и т.д.). Используя функциональный стиль, вы сразу видите, что программист намерен сделать, в отличие от использования циклов for, где все "выглядит" одинаково.
Сравните алгоритмы + лямбда:
iterator longest_tree = std::max_element(forest.begin(), forest.end(), [height]{arg0.height>arg1.height});
iterator first_leaf_tree = std::find_if(forest.begin(), forest.end(), []{is_leaf(arg0)});
std::transform(forest.begin(), forest.end(), firewood.begin(), []{arg0.trans(...));
std::for_each(forest.begin(), forest.end(), {arg0.make_plywood()});
со старыми добрыми циклами for;
Forest::iterator longest_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
if (*it.height() > *longest_tree.height()) {
longest_tree = it;
}
}
Forest::iterator leaf_tree = it.begin();
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
if (it->type() == LEAF_TREE) {
leaf_tree = it;
break;
}
}
for (Forest::const_iterator it = forest.begin(), jt = firewood.begin();
it != forest.end();
it++, jt++) {
*jt = boost::transformtowood(*it);
}
for (Forest::const_iterator it = forest.begin(); it != forest.end(); ++it{
std::makeplywood(*it);
}
(Я знаю, что этот кусок кода содержит синтаксические ошибки)
.