Cgfloat swift что это

В чем разница между использованием CGFloat и float?

Я, как правило, использую CGFloat повсюду, но мне интересно, получаю ли я бессмысленный «хит производительности» с этим. CGFloat кажется чем-то» тяжелее», чем float, верно? В какие моменты я должен использовать CGFloat, и что действительно имеет значение?

4 ответов

Я предлагаю вам инвестировать скромное время, необходимое для того, чтобы сделать ваше приложение 64-битным и попытаться запустить его как таковое, поскольку большинство Mac теперь имеют 64-битные процессоры, а Snow Leopard полностью 64-бит, включая ядро и пользовательские приложения. 64-разрядное руководство по переходу для Cocoa является полезным ресурсом.

CGFloat-обычный поплавок в 32-разрядных системах и дважды на 64-битных системах

таким образом, вы не получите никакого штрафа за производительность.

Как говорили другие, CGFloat-это поплавок на 32-битных системах и двойной на 64-битных системах. Однако решение об этом было унаследовано от OS X, где оно было принято на основе характеристик производительности ранних процессоров PowerPC. Другими словами, вы не должны думать, что float для 32-разрядных процессоров и double для 64-разрядных процессоров. (Я считаю, что процессоры ARM от Apple смогли обрабатывать двойники задолго до того, как они стали 64-битными.) Основной хит производительности использования двойников заключается в том, что они используют дважды памяти и поэтому может быть медленнее, если вы делаете много операций с плавающей точкой.

из исходного кода Foundation, в CoreGraphics’ CGBase.h :

Copyright (c) 2000-2011 Apple Inc.

здесь __LP64__ указывает, является ли текущая архитектура* 64-разрядная.

Источник

Cgfloat swift что это

Allow interchangeable use of CGFloat and Double types

When Swift was first released, the type of CGFloat presented a challenge. At the time, most iOS devices were still 32-bit. SDKs such as CoreGraphics provided APIs that took 32-bit floating point values on 32-bit platforms, and 64-bit values on 64-bit platforms. When these APIs were first introduced, 32-bit scalar arithmetic was faster on 32-bit platforms, but by the time of Swift’s release, this was no longer true: then, as today, 64-bit scalar arithmetic was just as fast as 32-bit even on 32-bit platforms (albeit with higher memory overhead). But the 32/64-bit split remained, mostly for source and ABI stability reasons.

In (Objective-)C, this had little developer impact due to implicit conversions, but Swift did not have implicit conversions. A number of options to resolve this were considered:

One important goal was avoiding the need for users to build for both 32- and 64-bit platforms in order to know their code will work on both, so option 3 was ruled out. Option 4 was not chosen mainly because of concern over handling of pointers to CGFloat (including arrays). Option 2 was ruled out due to challenges in the type-checker. So option 1 was chosen.

With several years’ hindsight and technical improvements, we can reevaluate these choices. 64-bit devices are now the norm, and even on 32-bit Double is now often the better choice for calculations. The concern around arrays or pointers to CGFloat turns out to be a minor concern as there are not many APIs that take them. And in the recent top-of-tree Swift compiler, the performance of the type-checker has significantly improved.

As the world has moved on, the choice of creating a separate type has become a significant pain point for Swift users. As the language matured and new frameworks, such as SwiftUI, have been introduced, CGFloat has resulted in a significant impedance mismatch, without bringing any real benefit. Many newly introduced APIs have standardized on using Double in their arguments. Because of this discrepancy, it’s not always possible to choose a “correct” type while declaring variables, so projects end up with a mix-and-match of Double and CGFloat declarations, with constant type conversions (or refactoring of variable types) needed. This constant juggling of types is particularly frustrating given in practice the types are transparently identical to the compiler when building for 64-bit platforms. And when building for 32-bit platforms, the need to appease the type-checker with the API at hand is the overriding driver of conversions, rather than considerations of precision versus memory use that would in theory be the deciding factor.

In order to address all of the aforementioned problems, I propose to extend the language and allow Double and CGFloat types to be used interchangeably by means of transparently converting one type into the other as a sort of retroactive typealias between these two types. This is option 2 in the list above.

Let’s consider an example where such a conversion might be useful in the real world:

This new conversion has the following properties:

Note that with the introduction of this new conversion, homogeneous overloads can be called with heterogeneous arguments, because it is possible to form a call that accepts both Double and CGFloat types or a combination thereof. This is especially common with operators.

Let’s consider following example:

The contextual type doesn’t affect the preferred conversion direction since the type-checker would always choose a solution with the fewest number of narrowing conversions possible, i.e.:

This is an additive change and does not have any material effect on source compatibility. This change has been tested on a very large body of code, and all of the expressions that previously type-checked with explicit conversions continued to do so.

Effect on ABI stability

This change introduces new conversions at compile-time only, and so would not impact ABI.

Effect on API resilience

This is not an API-level change and would not impact resilience.

Not to make this change and leave the painful ergonomics of the CGFloat type intact.

Restrict implicit conversions to “API boundaries” only. Such a rule would either imply the same behavior as proposed if operators/functions accept CGFloat arguments or introduce arbitrary restrictions like allowing conversions only across module boundaries or resilient ABIs, which would lead to confusing and inconsistent behavior where some calls would fail to type-check without an explicit conversion for no apparent reason (e.g. after an application has been refactored and slit into multiple modules or vice versa).

Another possible alternative would be to add new matching Double overloads to all APIs that currently accept CGFloat type. Such new APIs cannot be backward deployed unless they’re emitted directly into client binaries. In addition to bloating code size, this would also severely impact type checker performance much more than a targeted implicit conversion.

Holly Borla and Ben Cohen for all the help with writing and editing this proposal. Also Xiaodi Wu and other participants of the pitch discussion on Swift Forums.

Источник

Convert String to CGFloat in Swift

I’m new to Swift, how can I convert a String to CGFloat?

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

12 Answers 12

If you want a safe way to do this, here is a possibility:

If you change str to «bob», it won’t get converted to a float, while most of the other answers will get turned into 0.0.

For Swift 3.0, I’d do something like this:

In Swift 4, NSNumberFormatter has been renamed to NumberFormatter :

If you have to do this often, you can add an extension method to String :

Note that you should return a CGFloat? since the operation can fail.

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

or this if you are sure that string meets all requirements

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

While the other answers are correct, but the result you see will have trailing decimals.

To get a proper value back from the string, try the following:

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

You can make an extension that adds an init to CGFloat

Use it like so let x = CGFloat(xString)

in Swift 3.1

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

Simple one line solution:

This is kind of a work around, but you can cast it as an NSString, then get the float value, then initialize a CGFloat from that value. Example:

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

Источник

Swift 5.5. Что нового?

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это Cgfloat swift что это. Смотреть фото Cgfloat swift что это. Смотреть картинку Cgfloat swift что это. Картинка про Cgfloat swift что это. Фото Cgfloat swift что это

Swift 5.5. Что нового?

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

1. Впервые за все время развития языка, в этом обновлении большинство важных предложений Swift Evolution были очень тесно связаны между собой. Поэтому даже с учетом того, что все примеры приведены в определенной хронологии, некоторые из них станут понятны только после того, как вы изучите их в совокупности.
2. Некоторые представленные фичи до сих проходят стадию Swift Evolution, хотя в настоящее время они фактически доступны в последних бетах Swift 5.5. Это значит, что эти фичи могут дорабатываться даже после проведения WWDC21 и эта статья скорее всего будет доработана уже после конференции.

Async/await

Предложение SE-0296 вводит в Swift асинхронные функции, которые позволяют запускать сложный асинхронный код почти так же, как если бы он был синхронным. Это происходит в два этапа:

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

Представим, что нам нужно запросить у сервера 100_000 записей о погоде, чтобы затем обработать эти записи и рассчитать среднюю температуру за определенный период времени. После этого нам нужно будет отправить полученный результат обратно на сервер:

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

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

Вообще здесь есть несколько проблем:

Начиная с версии языка Swift 5.5, мы можем разгружать слишком сложную логику функций, помечая их как функции с асинхронно возвращаемыми значениями, без использования блоков замыканий:

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

При работе с асинхронными функциями следует соблюдать несколько простых правил:

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

Важно: создание асинхронной функции не означает, что она волшебным образом запускается параллельно с другим кодом. Если не указать иное, вызов нескольких асинхронных функций по-прежнему будет запускаться последовательно.

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

Async/await: коллекции

Ну и конечно же, в этом случае нам также необходимо находится в асинхронном контексте.

При работе с асинхронной последовательностью, её нужно перебирать в асинхронном контексте, используя для этого for await :

Ну и конечно же в этом случае нам также необходимо находится в асинхронном контексте.

Эффективная работа с read-only свойствами

Предложение SE-0304 представляет целый ряд подходов к выполнению, отмене и мониторингу параллельных операций в Swift и основывается на принципах async/await, асинхронных последовательностях, рассмотренных выше.

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

Самый простой асинхронный подход представляет из себя структурированный параллелизм (structured concurrency). При таком подходе используется атрибут @main для немедленного перехода в асинхронный контекст. Сам метод main() так же помечается, как асинхронный:

Заметка

Это значит, что мы можем вызывать метод fibonacci(of : ) в фоновом потоке столько раз, сколько нужно, чтобы вычислить первые 50 чисел последовательности:

Опять же, задача запускается, как только она была создана, и функция printFibonacciSequence() продолжит работу в каком бы потоке она ни была, пока вычисляются числа Фибоначчи.

Заметка

await taskOne.value гарантирует, что когда дело дойдет до чтения итоговых чисел, выполнение метода printFibonacciSequence() будет приостановлено до тех пор, пока вывод задачи не будет готов, после результат будет возвращен. Если возвращаемый результат не важен, и вы просто хотите, чтобы код запускался и останавливался в определенное время, то хранить задачу не нужно.

Для задач, которые выкидывают нераспознанные ошибки, чтение свойства value также автоматически вызовет ошибку. Мы могли бы написать функцию, которая выполняет две части работы одновременно, а затем ожидает их завершения:

Помимо выполнения операций, Task также предоставляет нам несколько статических методов для управления вызовами:

Давайте рассмотрим, как перевести выполнение задачи в спящий режим на одну секунду, а потом отменить её выполнение до того, как она завершится:

Заметка

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

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

Давай рассмотрим простой пример того, как работать с группами задач:

Заметка

Все задачи в группе должны возвращать один и тот же тип данных, поэтому для более сложного примера вам может потребоваться создать перечисление со связанными значениями (ассоциированными параметрами), чтобы получить именно то, что вы хотите. Более простая альтернатива представлена в отдельном предложении Async Let Bindings.

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

async let bindings

В качестве примера создадим структуру с тремя свойствами разного типа и три асинхронные функции, которые возвращают результаты того же типа, что имеют свойства структуры:

Важно: async let можно использовать только в том случае, если вы находитесь в асинхронном контексте.

Антракт

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

Continuations для взаимодействия асинхронных задач с синхронным кодом

Предложение SE-0300 представляет новый функционал, который помогает адаптировать старые API в стиле completion handler в современный асинхронный код.

В примере ниже, функция возвращает результат работы асинхронно в блоке замыкания:

В таких случаях можно использовать так называемые continuations. Это такие функции, которые по сути являются прокладками между старым и новым кодом. Они позволяют оборачивать старые функции с блоками замыканий в более современный API для работы с асинхронными вызовами.

Давайте обернем вызов функции fetchLatestNews в новую асинхронную функцию, используя для этого continuations:

Теперь мы можем получить нашу исходную функциональность в асинхронной функции:

Название метода withCheckedContinuation() связано с тем, что в нем происходит проверка на то, что метод resume() был действительно вызван и был вызван не более одного раза. Это важно, потому что, если метод не вызывать, то это приведет к утечке ресурсов. Если же его вызвать больше одного раза, то скорее всего у вас возникнут проблемы.

Важно: Метод resume() должен быть вызван не больше одного раза и должен быть вызван обязательно.

Акторы

Чтобы продемонстрировать решение проблемы, которую решают акторы, рассмотрим пример с классом RiskyCollector. Данный класс представляет из себя карточного коллекционера, который может обмениваться картами с другими такими же коллекционерами:

Если метод send(card:to:) вызвать более одного раза в одно и тоже время (это возможно сделать из разных потоков), то может произойти следующая цепочка событий:

В этом случае первый коллекционер отдает одну карту, когда второй получает две.

Акторы решают эту проблему при помощи изоляции своего внутреннего состояния. Это значит, что свойства и методы акторов не могут быть прочитаны извне, если они не выполняются асинхронно. Изменять значения свойств акторов извне вообще невозможно ни при каких обстоятельствах. При этом асинхронное поведение никак не влияет на производительность, так как Swift автоматически помещает все запросы в последовательную очередь, что позволяет избежать той самой гонки, о которой мы говорили выше, когда два или более потоков борются за выполнение одного и того же блока кода.

Принимая во внимание все вышесказанное, вместо класса RiskyCollector мы можем использовать актор SafeCollector :

В этом примере следует обратить внимание на несколько моментов:

Для ясности: экземпляр актора может использовать свои собственные свойства и методы как угодно (синхронно или асинхронно), но при взаимодействии с другим экземпляром актора вызовы всегда должны выполняться асинхронно. Благодаря этим изменениям Swift может гарантировать, что все изолированные свойства и методы акторов никогда не будут доступны одновременно из разных потоков. И что более важно, это делается во время компиляции, чтобы гарантировать безопасность.

Помимо изолированного состояния акторов, от классов их отличают еще два важных момента:

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

Акторы характеризуются: внутренним состоянием, которое не доступно извне, взаимодействием с другими акторами через асинхронные функции и действием в соответсвии с событиями, полученными от других акторов.

Глобальные акторы

Предложение SE-0316 позволяет изолировать с помощью акторов глобальное состояние потока данных от состояния гонки.

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

Представим, что у нас есть класс, который является неким менеджером хранения и по соображениям безопасности вносить какие либо изменения в базу данных мы можем только из основного потока:

В текущем исполнении все будет работать правильно, но с помощью @MainActor мы можем гарантировать, что метод save() всегда будет вызываться только из основного потока, как если бы мы специально вызывали его при помощи DispatchQueue.main :

Протокол Sendable и оболочка @Sendable

SE-0302 добавляет поддержку «отправляемых» данных, то есть данных, которые можно безопасно передавать в другой поток. Это достигается с помощью нового протокола Sendable и атрибута @ Sendable для функций.

К таким данным относятся:

Все перечисленные выше типы данных теперь подписаны под протокол Sendable, и их можно безопасно передавать между разными потоками.

Что же касается пользовательских типов данных, то тут все зависит от того, чем конкретно они являются:

Атрибут @Sendable в функциях или замыканиях, позволяет выполнять код параллельно, но с определенными ограничениями, для того, чтобы разработчики не стреляли сами себе в ноги:

Атрибутом @Sandable можно помечать и свои собственный функции и замыкания:

Работа с такими функциями должна выполняться по тем же правилам.

# if для постфиксных членов выражений

SE-0308 позволяет Swift использовать условия #if в выражениях с постфиксными членами. Звучит непонятно, поэтому проще будет показать на примере, который решает проблему, обычно наблюдаемую в SwiftUI:

Для представлений теперь можно вызывать опциональные модификаторы. Это изменение позволяет нам создавать текстовое представление с двумя разными размерами шрифта в зависимости от того, используем ли мы iOS или другую платформу.

Можно делать вложенные условия, хотя они довольно сложны для восприятия:

При желании можно использовать совершенно разные постфиксные выражения:

Взаимозаменяемое использование типов CGFloat и Double.

SE-0307 представляет небольшое, но важное улучшение: Swift теперь может неявно конвертировать значения с типом CGFloat в Double в большинстве мест, где это может понадобиться:

Совместимость Codable и перечислений со связанными значениями

Данное перечисление имеет один кейс без каких либо значений, второй кейс имеет одно связанное значение с типом Int и третий кейс с двумя связанными целочисленными значениями.

Создадим массив с прогнозом погоды на базе этого перечисления, чтобы затем конвертировать его в JSON:

lazy в локальной зоне видимости

Ключевое слово lazy (ленивый) позволяет осуществлять отложенную инициализацию свойства. Обратиться к ленивому свойству невозможно до тех пор, пока инициализация класса полностью не завершится. Раньше ключевым словом lazy можно было пометить только свойства класса. Начиная с версии Swift 5.5, lazy можно использовать и в локальных зонах видимости методов:

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

Оболочки над свойствами для параметров функций и замыканий

Благодаря предложению SE-0293 оболочки над свойствами теперь можно применять к параметрам функций и замыканий. Параметры, переданные таким образом, как и обычные параметры остаются неизменными, и вы также можете получить доступ к базовому типу оболочки свойств, используя нижнее подчеркивание.

В качестве примера мы могли бы написать функцию, которая принимает целое число и выводит его на консоль:

Соответсвенно, в параметр данной функции мы можем передать любое целочисленное значение практически из любого диапазона, в том числе и отрицательное:

Теперь мы можем реализовать функцию, которая будет выводить на консоль очки в указанном диапазоне, используя для этого нашу оболочку:

Расширение поиска статических членов в дженериках

SE-0299 позволяет Swift выполнять статический поиск членов протоколов в дженерик функциях. Опять таки звучит непонятно, поэтому сразу рассмотрим пример. В SwiftUI для определения внешнего вида некоторых элементов интерфейса, таких как граница текстового поля или внешний вид Toggle в модификаторы приходится передавать названия структур, отвечающих за внешний вид:

С обновлением языка это должно выглядеть примерно так:

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

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

До появления текущего нововведения мы могли бы включить светлую тему для домашнего экрана следующим образом:

Чтобы упростить доступ к светлой теме, мы могли бы определить статическое свойство light в протоколе Theme следующим образом:

Однако использование такого подхода вкупе с дженерик методом theme() нашего протокола до версии Swift 5.5 было невозможно, поэтому приходилось подставлять LightTheme() каждый раз. Однако теперь это стало возможным:

И напоследок.

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

Хотя я попытался охватить все основные новые функции Swift 5.5, есть еще кое-что, о чем я не рассказал:

В любом случае, я не собираюсь здесь спекулировать дальше, просто хочу сказать, что с нетерпением жду возможности перечитать эту статью после WWDC21, потому что подозреваю, что мы увидим ключевые части фреймворков Apple, уже адаптированные под Swift 5.5.

Что я могу сказать точно, так это то, что команда, которая трудится над Swift, работает невероятно усердно, чтобы предоставить потрясающую коллекцию изменений за относительно короткое время. И очень многим мы обязаны комьюнити Swift Evolution. Чтобы в Swift появились акторы потребовалось сделать семь презентаций и два предложения, прежде чем это утвердили.

Итак, команде Swift: спасибо за то, что вы действительно сделали все возможное, чтобы создать что-то невероятное в сжатые сроки. И всем остальным: пристегнитесь, потому что WWDC21 будет чертовски крутой…

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *