Pull to refresh

Comments 17

После нескольких лет разработки с использованием Xamarin я для себя решил что чем меньше прослоек между приложением и платформой — тем лучше.
Справедливости ради хочу отметить, что Xamarin прослойка очень тонкая. Ему от .NET достался p/Invoke, то есть любые C библиотеки подключаются влет. Там также есть неплохой набор инструментов для работы с ObjC и Java кодом.

Вот Xamarin.Forms это реально уже «толстая» прослойка, аналогично React.Native и Appcelerator Titanium.
А в чем плюсы разработки на Xamarin если не использовать Forms? Какую проблему он решает в таком случае? Насколько я знаю нельзя ни собрать ни опубликовать IOS апп без MacOS.
Плюс в c# и в общей доменной области
Как уже верно отметили плюс в общем коде, общим получается где-то 30% кода. Лично для меня еще очень важный плюс — можно внедрить в команде один подход к разработке.
Пример — все View Model сделаны в общем коде, в итоге контроллеры (в iOS) и фрагменты (в Android) получаются практически одинаковыми, так как основаны на одном API.
А если в Android используется MPV, по понятным причинам, а в IOS VIPER, то в таком случае мне кажется это усложняет такой подход. 30% не такой уж и плюс учитывая что мобильные приложения это тонкий клиент, то там редко бывает такой обьем логики которую нельзя реализовать на нативной платформе довольно быстро. Я лично не встречал «больших» приложений (уровня Tinder, Telegram и т.д. ) на Xamarin.
Тут хотелось бы уточнить — дело даже не в «толщине» прослойки, а в самом факте ее существования и законе Мерфи.
Самый яркий пример (было это года два тому назад) — приложение падало при запуске на некоторых моделях смартфонов, причем падало при вызове такого базового функционала как DateTime.Now. Спустя месяц или два для Xamarin был выпущен багфикс. Но оказывается что проблема актуальна для некоторых моделей до сих пор и даже исключение то же самое выбрасывается.

Поэтому мой выбор — Java/Swift.

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


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


С DateTime много нюансов:


Это и то, что Now/UtcNow — свойства, а не методы
(свойство предполагает неизменяемость при повторном вызове, если программист явно не менял, состояние объекта, и отсутствие исключений — а они как раз могут быть при получении времени из системы)


Путаница с DateTimeKind и с конвертацией между Kind, приведшая к появлению надстройки в виде DateTimeOffset.


Недокументированность поведения в той части, что UtcNow более "нативный" для системы и быстрый, чем Now


То, что методы типа AddDays работают с вещественными величинами, а не целыми (вопросы производительности и особенностей float-арифметики).


Определенные проблемы при де/сериализации.


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


Однако, при этом ведь в Java не все так гладко с датами? Неслучайно ведь в Java 8 появился новый DateTime API, а старый объявлен legacy.

Это и то, что Now/UtcNow — свойства, а не методы
(свойство предполагает неизменяемость при повторном вызове, если программист явно не менял, состояние объекта, и отсутствие исключений — а они как раз могут быть при получении времени из системы

Как вы можете это говорить в эру многопоточности?)

Ваш вопрос требует пояснений — вы имеете в виду, что если мы обеспечили неизменяемость свойства при отсутствии явного изменения состояния объекта в однопотоке, то при многопотоке свойство не защищено от изменений?
Так это давно известно — что потокобезопасность объекта нужно обеспечивать дополнительно — либо при разработке самого объекта (точнее, его класса), либо при работе с объектом со стороны вызывающего кода.


Впрочем, больше удивила ваша "эра многопоточности") — Попахивает чуть ли не 90-ми)
Сейчас же вовсю в тренде однопоток с запуском отдельных процессов (не потоков) для выполнения параллельных задач (те же Rails),
либо вызов многопоточного кода в синхронном стиле — go-рутины, .NET-вские async/await.


Если брать async/await — много вы видели в реальных проектах не обычный await метода в синхронном стиле, а как минимум запуск Task, переход к другому коду, затем возвращение в текущем же методе к Task и ожидание его результата (простейший пример из MSDN)?
Уж не говорю о применении по прямому назначению I​Async​Operation​With​Progress.

Я имею ввиду, что ечли вы обращаетесь к объекту каркаса, который подразумевает непрерывное и независимое существование, то это естественно, что его состояние изменяется независимо от вас.
А насчет вашего примера, то я например использую это давольно часто. Например мне надо запросить информацию из удаленного сервиса, и плюс к этому у меня есть объемная независимая задача

Это правило, отличающее свойства от методов, работает и для случае многопотока:


Если при этом другой код (из другого потока) вызывал методы, меняющие состояние объекта, то ок.


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


Now — как раз тот случай, когда это должен быть метод.
Тем более, что свойство должно быть легковесным, и не порождать недетерминированных исключений (максимум — InvalidOperationException, если для текущего состояния объекта свойство не имеет смысла — но это уже не очень хороший дизайн).
Из вашего примера следует, что Now не соответствует сути свойства.

Если при этом другой код (из другого потока) вызывал методы, меняющие состояние объекта, то ок.

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


В случае с DateTime.Now все намного хуже — тут без правок в самой платформе проблема нерешаема. Даже если в самом приложении явно не вызывать DateTime.Now, то проблема все-равно остается — например, при обращении к серверу по https (т.е. любая .NET-библиотека, использующая внутри себя DateTime.Now будет крашить приложение).

Из других неприятных вещей:
необходимость ручной замены некоторых файлов в IDE (если упремся в лимит 64к классов на Android)
— ужасающе медленная работа axml-редактора в VS (настолько, что порой проще axml-руками поправить)
В случае с DateTime.Now все намного хуже ...

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

Скажите пожайлуйста пример, где DateTime.Now проблема, кроме тех, где виноват именно .net, а не Android например(java)
Уточнение — проблема с DateTime.Now имеет место в платформе Xamarin (не в .NET) на некоторых моделях устройств. Связана с тем как Xamarin.Android парсит инфо о часовых поясах, полученную от ОС Android
Sign up to leave a comment.