Поверните строку в список; то вы можете изменить символы в отдельности. Затем вы можете вернуть его вместе с .join
:
s = 'a;b;c;d'
slist = list(s)
for i, c in enumerate(slist):
if slist[i] == ';' and 0 <= i <= 3: # only replaces semicolons in the first part of the text
slist[i] = ':'
s = ''.join(slist)
print s # prints a:b:c;d
Нет, есть определенные моменты, когда вы не хотели бы использовать [unowned self]
. Иногда вы хотите, чтобы замыкание захватывало себя, чтобы убедиться, что оно все еще вокруг к тому времени, когда вызывается замыкание.
Если вы делая запрос асинхронной сети, вы хотите, чтобы закрытие сохраняло self
, когда запрос заканчивается. Этот объект может быть иначе освобожден, но вы все еще хотите иметь возможность обрабатывать завершение запроса.
unowned self
или weak self
Единственный раз, когда вы действительно хотите использовать [unowned self]
или [weak self]
, когда вы создадите сильный ссылочный цикл . Сильный ссылочный цикл - это когда существует право собственности на объекты, в которых объекты становятся друг с другом (может быть, через третью сторону), и поэтому они никогда не будут освобождены, потому что они оба гарантируют, что друг друга будут придерживаться.
В конкретном случае закрытия вам просто нужно понять, что любая переменная, на которую ссылаются внутри нее, получает «собственность» по закрытию. Пока закрытие вокруг, эти объекты гарантированно будут вокруг. Единственный способ остановить это право собственности - сделать [unowned self]
или [weak self]
. Поэтому, если класс владеет закрытием, и это закрытие фиксирует сильную ссылку на этот класс, тогда у вас есть сильный ссылочный цикл между закрытием и классом. Это также включает в себя, если классу принадлежит то, что принадлежит закрытию.
В примере на слайде TempNotifier
владеет закрытием через onChange
. Если они не объявили self
как unowned
, замыкание также будет иметь self
, создавая сильный опорный цикл.
unowned
и weak
Разница между unowned
и weak
заключается в том, что weak
объявляется как необязательный, а unowned
- нет. Объявив это weak
, вы получите дело с тем, что в какой-то момент он может остаться в закрытии. Если вы попытаетесь получить доступ к переменной unowned
, которая будет равна нулю, это приведет к сбою всей программы. Поэтому используйте unowned
, когда вы уверены, что переменная всегда будет вокруг, а закрытие вокруг
Вот блестящие цитаты из Форумы разработчиков Apple описали вкусные детали:
unowned
vs unowned(safe)
vs unowned(unsafe)
blockquote>
unowned(safe)
- это ссылка, не относящаяся к владельцам, которая утверждает, что объект все еще жив. Это похоже на слабую необязательную ссылку, которая неявно распаковывается сx!
каждый раз, когда к ней обращаются.unowned(unsafe)
походит на__unsafe_unretained
в ARC - это не-владеющая ссылка, но нет проверки времени выполнения, что объект все еще жив при доступе, поэтому оборванные ссылки попадут в мусорную память.unowned
всегда является синонимом дляunowned(safe)
в настоящее время, но предполагается, что он будет оптимизирован дляunowned(unsafe)
в сборках-Ofast
, когда проверки времени выполнения отключены.
unowned
vsweak
blockquote>
unowned
фактически использует гораздо более простую реализацию, чемweak
. Объекты Native Swift несут два подсчета ссылок, а ссылкиunowned
нажимают недостоверный счетчик ссылок вместо значения strong . Объект деинициализируется, когда его число strong достигает нуля, но оно фактически не освобождается до тех пор, пока счетчик ссылок unowned также не достигнет нуля. Это приводит к тому, что память удерживается немного дольше, когда есть неопубликованные ссылки, но обычно это не проблема, когда используетсяunowned
, потому что связанные объекты должны иметь почти равные сроки жизни в любом случае, и это намного проще и ниже накладных расходов чем реализация на стороне стола, используемая для обнуления слабых ссылок.Обновление: в современном Swift
weak
внутренне используется тот же механизм, что иunowned
. . Таким образом, это сравнение неверно, поскольку оно сравнивает Objective-Cweak
с Swiftunonwed
.Причины
Какова цель сохранения памяти в памяти после владения ссылками достигают 0? Что произойдет, если код попытается что-то сделать с объектом, используя неопубликованную ссылку после того, как он деинициализирован?
Память сохраняется в памяти, так что ее значения сохранения остаются доступными. Таким образом, когда кто-то пытается сохранить сильную ссылку на незарегистрированный объект, среда выполнения может проверить, что сильный счетчик ссылок больше нуля, чтобы гарантировать сохранность объекта.
Что происходит с владением или отсутствием ссылки на объект? Является ли их время жизни отделенным от объекта, когда он деинициализирован или их память также сохраняется до тех пор, пока объект не будет освобожден после того, как будет освобождена последняя незанятая ссылка?
Все ресурсы, принадлежащие объекту, освобождаются как вскоре после того, как будет удалена последняя сильная ссылка объекта, и будет запущен ее запуск. Недопустимые ссылки сохраняют память только в стороне от заголовка с подсчетом ссылок, его содержимое является нежелательным.
blockquote>Возбуждено, да?
Если self может быть nil в использовании замыкания [слабый self].
Если self никогда не будет nil в закрытии использовать [unowned self].
Документация Apple Swift имеет большой раздел с изображениями, объясняющими разницу между использованием сильных, слабых и незанятых в замыканиях:
Согласно Apple-doc
blockquote>
- Слабые ссылки всегда имеют необязательный тип и автоматически становятся нулями, когда экземпляр, который они ссылаются, освобождается.
- Если захваченное задание никогда не станет нулевым, оно всегда должно быть записано как неосновная ссылка, а не слабая ссылка
Пример -
// if my response can nil use [weak self] resource.request().onComplete { [weak self] response in guard let strongSelf = self else { return } let model = strongSelf.updateModel(response) strongSelf.updateUI(model) } // Only use [unowned self] unowned if guarantees that response never nil resource.request().onComplete { [unowned self] response in let model = self.updateModel(response) self.updateUI(model) }
Я думал, что добавлю некоторые конкретные примеры специально для контроллера вида. Многие объяснения, а не только здесь, о переполнении стека, действительно хороши, но я лучше работаю с примерами реального мира (на самом деле у @drewag было хорошее начало):
weak
, поскольку они долговечны. Контроллер вида может закрыться до завершения запроса, поэтому self
больше не указывает на действительный объект при вызове закрытия. unowned
, поскольку, как только контроллер просмотра уйдет, кнопка и любые другие элементы, которые она может ссылаться на self
, уходят одновременно. Блок блокировки также уйдет в одно и то же время. class MyViewController: UIViewController {
@IBOutlet weak var myButton: UIButton!
let networkManager = NetworkManager()
let buttonPressClosure: () -> Void // closure must be held in this class.
override func viewDidLoad() {
// use unowned here
buttonPressClosure = { [unowned self] in
self.changeDisplayViewMode() // won't happen after vc closes.
}
// use weak here
networkManager.fetch(query: query) { [weak self] (results, error) in
self?.updateUI() // could be called any time after vc closes
}
}
@IBAction func buttonPress(self: Any) {
buttonPressClosure()
}
// rest of class below.
}
Здесь есть несколько отличных ответов. Но недавние изменения в том, как Swift реализуют слабые ссылки, должны изменить все слабое самосогласование или несостоявшиеся решения для самопомощи. Раньше, если бы вам нужна была лучшая производительность с использованием незадействованного «я», это было бы лучше слабого «я», если бы вы могли быть уверены, что «я» никогда не будет никчемным, потому что доступ к незаслуженному «я» намного быстрее, чем доступ к слабому «я».
Но Майк Эш задокументировал, как Swift обновил реализацию слабых варов для использования боковых столов и как это существенно улучшает слабую самоэффективность.
https://mikeash.com/pyblog/friday- qa-2017-09-22-swift-4-weak-references.html
Теперь, когда нет значительного снижения производительности для слабого пользователя, я считаю, что мы должны по умолчанию использовать его идти вперед. Преимущество слабого «я» заключается в том, что он является дополнительным, что значительно упрощает создание более правильного кода, в основном это причина, по которой Свифт - такой замечательный язык. Вы можете подумать, что знаете, какие ситуации безопасны для использования незадействованного «я», но мой опыт, рассматривающий множество других кодексов разработчиков, больше всего этого не делает. Я зафиксировал много сбоев, когда незанятое я было освобождено, обычно в ситуациях, когда фоновый поток завершается после того, как контроллер освобожден.
Ошибки и сбои - это наиболее трудоемкие, болезненные и дорогие части программирования. Сделайте все возможное, чтобы написать правильный код и избежать их. Я рекомендую сделать это правилом, чтобы никогда не приводить в действие разворот оппонентов и никогда не использовать незадействованное я, а не слабое я. Вы не потеряете ничего, потеряв время, когда разворачивается сила, и незанятое я действительно безопасно. Но вы получите много от устранения трудно найти и отладить сбои и ошибки.
Я написал статью об этом расширении этого ответа (глядя на SIL, чтобы понять, что делает ARC), проверьте здесь .
Предыдущие ответы не дают прямых правил о том, когда использовать друг друга и почему, поэтому позвольте мне добавить несколько вещей.
Непринятые или слабое обсуждение сводится к вопросу о времени жизни переменной и замыкания, которое ссылается на нее.
У вас может быть два возможных сценария:
[unowned self]
, используемый во многих примерах небольших замыканий, которые делают что-то в контексте их родителя и что нигде не упоминаются нигде, не переживают своих родителей. [weak delegate]
, который вы можете увидеть в некоторых примерах замыкания, ссылаясь на полностью не связанный (пожизненный) объект делегирования.
Котировка Джо Гроффа из твиттера :
Unowned быстрее и позволяет неизменность и неоптимальность.
Если вам не нужен слабый, не используйте его.
blockquote>Вы найдете больше о неработающих внутренних функциях
*
здесь .
*
Обычно также упоминается как незаслуженный (безопасный), указывающий, что проверки выполнения (которые приводят к сбою за недопустимые ссылки) выполняются перед доступом к незаслуженному ссылка.
[weak self]
в асинхронном сетевом запросе находится в контроллере представления , где этот запрос используется для заполнения представления. Если пользователь отступает, нам больше не нужно заполнять представление, и нам не нужна ссылка на контроллер вида. – David James 30 March 2016 в 14:41weak
ссылки также устанавливаются наnil
, когда объект освобождается.unowned
ссылок нет. – BergQuester 2 November 2017 в 17:16unowned
используется дляnon-Optional
, а дляOptional
используетсяweak
, поэтому нашself
равенOptional
илиnon-optional
? – Muhammad Nayab 16 January 2018 в 14:25