All streams
Search
Write a publication
Pull to refresh
24
0
Ивлев Александр @ivlevAstef

Senior/Lead iOS software developer

Send message
«Мобильные игры под Android пишут на Java и C++, под IOS — Swift и Objective-C.»
Не соглашусь — в обоих случаях пишут на с++ и очень редко на языках платформы. В добавок не стоит забывать про unity которая позволяет писать на c# или js, для мобильных приложений.

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


И пожалуйста, не надо править так: https://ru.wikipedia.org/wiki/Блокировка_с_двойной_проверкой :) на такое тоже часто натыкаюсь :)


P.S. долго думал куда об этом написать, решил всеже развить тему про syncQueue.
P.P.S. На самом деле я не понимаю откуда берется такая любовь к созданию потоков для синхронизации. Вы не один такой, я часто вижу подобный код, но не понимаю чем не устраивает то что созданно для синхронизации, а именно: OSSpinLock или objc_sync_enter/exit. Они быстрее, едят меньше памяти и не нужно создавать странный код чтобы получить значение из тела блока.

Большой список, что-то важно что-то нет:
Валидацию корректности до момента исполнения — в памяти есть полный граф (надуманная проблема, так как в семантике EasyDi проблема может быть помойму только одна — зацикливание, если объявили не objectGraph)


Получение множества объектов по заданному критерию (например есть N реализаций одного протокола)


Уменьшение избыточности синтаксиса — не надо придумывать имена — тип является именем (но есть в этом и преимущество)


Поддержка позднего связывания — к примеру есть протокол, но наличие его реализации не гарантируется, она может быть, а может и не быть. (Та причина почему мы отказались от тайфуна).


Подробнее про позднее связывание:
У нас есть N модулей. В одном модуле описаны протоколы — сервисы. В разных сборках мы имеем разную комбинацию этих модулей, соответственно в разных сборка у нас или есть или нету реализации этих протоколов. Возникает проблема — под каждую сборку надо писать немного разное объявление DI.


Ну и этоже проблема пораждает другую проблему — модульности как такой нету — один Assembly должен знать о другом Assembly из другого модуля, что не всегда приемлимо, см. выше.


Я бы выделил две вещи:
Позднее связывание, очень важная вещь на больших проектах, и мало важная на мелких
Получение множества объектов — упрощает всякие паттерны типа Observer.

О, наконец токи кто-то написал нормально с точки зрения внешнего синтаксиса Typhoon на swift.


Реализация в 200 строчек очень сильно радует — осознал что мои 1к строчек можно видимо оптимизировать.


Правда кое чего думаю не хватит многим:
Внедрение во ViewController так чтобы его не трогать — сейчас я так понял предполагается это делать в функции awakeFromNib, хотелось бы чтобы оно автоматически вызывалось.


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

хм…


NSDictionary* info = result["info"]
if (![info isKindOfClass: NSDictionary.class]) {
  return
}
NSLog("%@", info["title"])

Вроде так?
Вот enum свифта перевести в enum Obj-C, куда посложнее задача, если первый используется не только как обычное перечисление.

Еще раз перечитал статью.
А почему не использовать в качестве type реальный тип класса?


тогда switch будет похож на:


switch type(of: self) {
  case ViewController1.self:
   ...
  case ViewController2.self:
   ...
}

Правда именно так не разрешено сделать, но всегда есть String(describing:) который можно красиво обернуть через расширение в какой-нибудь статический метод/свойство.


В этом случае не нужно добавлять enum и инициализировать его во всех ViewController + интеллисенс будет позволять легко переходить на каждый из них.

Да пожалуй, первый пункт на самом деле проглядел. Ну и по второму и третьему пункту соглашусь.


Так что да, идея на самом деле отличная. Возможно попробую у себя как-нибудь в проекте, но сходу больше проблем не вижу.
Есть правда одна — сочетание со storyboard, так как у нас в компании принято разрабатывать через него.


Покрайней менее, это в разы проще моего сложного VCRouter который решает туже задачу.

А мне идея сама понравилась — она достаточно красивая для внешнего использования.


Но проблема идеи — она не универсальна и плохо сочетаема с ограничением доступа — по факту теперь можно вызвать переход с любого экрана на любой.


Если идею расширить чтобы можно было: передавать параметры и ограничить доступ по переходам — то сталобы хорошо.


На самом деле то что описано в статье, это почти эквивалент того что я называю Навигатором.
Навигатор: Некий класс содержащий набор методов с переходами между экранами. Он наследуеться от десятка протоколов, в которых кокраз таки и содержаться эти методы.
После чего этот класс, но по протоколам, мы подсовываем во все ViewController-ы.


Такой подход не решает одной проблемы — не видно карты всех переходов целиком, что на мой взгляд кокраз таки и отличает Роутер от Навигатора — по первому видны все "маршруты" которые есть.


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

Да так можно сделать на Swift, но начиная с Swift 3 описанная проблема тоже решается — появилось дополнительное ключевое слово `open`, которое отличается от `public`.
Все тот-же пример:
Создается библиотека с открытым АПИ. В ней есть класс Payment и в ней реализованы: CashPayment, CardPayment, GiftPayment, PayPalPayment.
Если разработчик библиотеки хочет дать возможность сторонним разработчикам наследоваться от всех этих классов, то их стоит объявить `open`.
Если только от Payment то все будут `public`, а Payment `open`.
И чтобы закрыть полностью данную возможность, надо все объявить `public`.

То есть `public` позволяет наследовать внутри библиотеки, но не позволяет наследоваться за пределами библиотеки, а `open` позволяет наследоваться и внутри и за пределами.

Поэтому описанная проблема, имеет решение на Swift 3.0
Спасибо. Рад слышать, что кому-то интересен мой проект.
Carthage, а заодно и SwiftPM постараюсь добавить в ближайшее время.

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

Information

Rating
Does not participate
Location
Новосибирск, Новосибирская обл., Россия
Date of birth
Registered
Activity