/ / Декларациите от разширенията все още не могат да бъдат преодолени в Swift 4 - ios, разширителни методи, swift4

Декларациите от разширенията все още не могат да бъдат отменени в Swift 4 - ios, методите за разширение, swift4

Наскоро мигрирах кода си Swift 4, Има проблем, пред който съм изправен разширения, т.е.

Декларациите от разширенията все още не могат да бъдат отменени

Вече прочетох няколко публикации, регенериращи този проблем. Но никой от тях не забавлява сценария, описан по-долу:

class BaseCell: UITableViewCell
{
//Some code here...
}

extension BaseCell
{
func isValid() -> String?
{
//Some code here...
}
}

class SampleCell: BaseCell
{
//Some code here...

override func isValid() -> String? //ERROR..!!!
{
//Some code here...
}
}

Според Apple,

Разширенията могат да добавят нова функционалност към тип, но не могат да заменят съществуващите функции.

Но в горния сценарий, аз не съм пренебрегващ метода isValid() в разширение. Той е преименуван в SampleCell самата класова дефиниция. И все пак дава грешката.

Отговори:

5 за отговор № 1

Но в горния сценарий, аз не съм пренебрегващ метода isValid() в разширение.

isValid се обявява в разширение.

Грешката почти казва, че ако функцията е обявена по този начин, това не може да бъде пренебрегнато.

Изявлението е валидно и за двете от разширение и в разширение.


2 за отговор № 2

Мисля, че това е очевидно. декларации ОТ разширенията все още не могат да бъдат преодолени

Опитвате се override функцията func isValid() -> String? който е обявен в рамките на extension на BaseCell, а не на BaseCell самия клас.

Очевидно е, че не можете да замените нещо, което е било обявено в разширение.

Надявам се, че е полезно.


2 за отговор № 3

В Swift 3 сте успели да преодолеете функцията на разширението, ако разширението е от клас, който се получава от Objective-C (http://blog.flaviocaetano.com/post/this-is-how-to-override-extension-methods/), но предполагам, че не е възможно сега в Swift 4. Разбира се, можете да направите нещо подобно:

protocol Validity {
func isValid() -> String?
}

class BaseCell: UITableViewCell, Validity {

}

extension Validity
{
func isValid() -> String? {
return "false"
}
}

class SampleCell: BaseCell {

func isValid() -> String? {
return "true"
}
}


let base = BaseCell()
base.isValid() // prints false

let sample = SampleCell()
sample.isValid() // prints true

0 за отговор № 4

Той е невалиден в Swift, но не и в Цел-С. Така че, ако вашият подпис на метода го позволява (без забранени конструкции), можете да го декларирате @objc func myMethod() и да го замени свободно в Суифт.


0 за отговор № 5

Аз също имах огромно наследство от код Swift 3, който използвашетози стар трик, за да постигнем това, което исках, така че когато се преместих в Swift 4 и започнах да получавам тези грешки, бях малко объркан. Не бойте се, има решение.

Тази грешка е свързана с начина Swift 4съставя класовете и новия начин, по който третира класовете и функциите на Целка-С. При Swift 3, ако даден клас е получен от NSObject, тогава всички променливи и функции в този клас ще използват конвенциите за динамично наименуване и търсене на Objective C. Този подход възпрепятства способността на Swift да оптимизира кода и да подобри ефективността на кода и размер.

За да се преодолеят тези санкции, в Swift 4, само променливи и функции, изрично маркирани с @objc получавате лечение с Цели-C, всичко останало използва стандартни Swift конвенции: оттук и грешката.

Въоръжени с тези знания, решението на проблема ви е да маркирате функциите в разширението, за което искате да бъдете заместени @objc, след това в часовете за деца, да замени функцията, но не забравяйте да включите @objc маркер, така че кодът ви ще бъде извикан по време на изпълнение.

ВНИМАНИЕ Малкото е тук: ако забравите да включите @objc в override, компилаторът няма да се оплаче, но кодът ви няма динамично търсене, така че никога няма да се нарича по време на изпълнение.

Така че вашият код трябва да изглежда малко по следния начин:

class BaseCell: UITableViewCell {
//Some code here...
}

extension BaseCell {
@objc func isValid() -> String? {
//Some code here...
}
}

class SampleCell: BaseCell {
//Some code here...

@objc override func isValid() -> String? {
//Some code here...
}
}