Почему viewWithTag и некоторые другие методы не переименованы в Swift 3?

#swift3 #fluent #api-design

#swift3 #свободно #api-дизайн

Вопрос:

В Swift 3 многие методы были переименованы. Согласно одной из сессий на WWDC, предлоги в именах методов перемещаются в имя параметра:

 UIView.animateWithDuration(1)
 -> UIView.animate(withDuration: 1)

UIStoryboard.instantiateViewControllerWithIdentifier("some stuff")
 -> UIStoryboard.instantiateViewController(withIdentifier: "some stuff")
  

Я думал, что viewWithTag(1) они будут переименованы в view(withTag: 1) , но это не так!

Это даже упоминается в руководстве API:

Особенно когда тип параметра — NSObject, Any, AnyObject или фундаментальный тип, такой как Int или String, информация о типе и контекст в точке использования могут не полностью передавать намерение. В этом примере объявление может быть ясным, но сайт использования расплывчатый.

 func add(_ observer: NSObject, for keyPath: String)
grid.add(self, for: graphics) // vague
  

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

 func addObserver(_ observer: NSObject, forKeyPath path: String)
grid.addObserver(self, forKeyPath: graphics) // clear
  

Я также обнаружил, что SKNode.addChild это тоже не переименовано!

Вопрос:

Почему эти методы не переименованы? Они забыли о них? Или есть исключения из правил API? Если да, то что это такое?

Ответ №1:

Я изучаю алгоритм, описанный в Swift Evolution 0005.

  1. viewWithTag

Первый шаг сокращения имени — это:

  1. Удалите тип результата из заголовка преобразований, сохраняющих тип. В частности, когда

    • тип получателя совпадает с типом результата
    • и имя типа сопоставляется в начале первой части селектора
    • и за совпадением следует предлог

view часть на самом деле удаляется первой.

forTag Также удаляется на шаге 3, поэтому результатом является пустой селектор.

Это сталкивается с

Ограничения на сокращение

  • Никогда не делайте часть селектора полностью пустой.

Поэтому обрезка не выполняется.

  1. addChild

addChild , addSubview , addGestureRecognizer следуйте все тому же шаблону, на самом деле в спецификации есть пример:

  • Никогда не удаляйте суффикс из базового имени метода, который соответствует свойству заключающего класса:

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

… Если бы мы отбросили GestureRecognizer , оставив только add , мы получили бы метод, который концептуально изменяет gestureRecognizers свойство, но использует для этого слишком общее имя:

В общем, они не могут забыть о некоторых методах, потому что переименование (импорт) происходит автоматически.

Комментарии:

1. Что насчет addChild метода? Разве это не должно быть add ? Это по другой причине?

2. @Sweeper расширил ответ. Не заметил, что вы просили два разных метода. Алгоритм довольно сложный, но он имеет большой смысл.