2015-11-02 2 views
3

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

Проблемы, которые возникают у меня, как мы можем пометить классы как окончательные, но все же включить подкласс класса? Кто-нибудь действительно сталкивается с этой проблемой или я должен отказаться от последнего ключевого слова из моей декларации?

Любые предложения были бы замечательными или, если они не сообщают мне, что я не делаю это правильно.

Thanks, Mike.

+0

финал финал ... нет подклассов из выпускного класса. – user3441734

ответ

1

Компилятор использует статическую отправку, когда вы отмечаете что-то как final вместо динамической отправки. Это имеет значительные преимущества в производительности. Это также прямо противоречит тому, что он может что-то издеваться, поскольку вся точка статической отправки заключается в том, что ему не нужно определять, какую версию метода вызывать.

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

+0

Итак, как можно было бы провести тестирование единицы, которая зависит от окончательного класса от сторонней библиотеки? Обычно я просто подклассы и меняю его, но похоже, что это не так. – Tres

+0

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

1

Я знаю, что эта ветка немного устарела, но я думал, что буду комментировать. Другим вариантом будет переход по протоколу. Определите свой интерфейс public для вашего последнего класса в протоколе и сделайте final class реализовать этот протокол. Тогда все, что вам нужно сделать, - это издеваться над протоколом, и ваш класс остается окончательным. Это дает вам вашу статическую диспетчеризацию и ваши издевательства. Я не знаю точно, является ли это лучшим вариантом, но это тот, который я использовал в нашем каркасном здании, чтобы мы могли протестировать наш код фреймворка, предоставляя оптимизированные бинарные файлы для приложений-пользователей.

internal protocol MockableProtocol { 
    func deleteItem(_ itemId: String) -> Bool 
    func fetchAllItems() -> [CustomObject] 
    func fetchItem(for id: String) -> CustomObject? 
} 

internal final class MyFinalClass: MockableProtocol { 
    func deleteItem(_ itemId: String) -> Bool { 
     // Your code here 
    } 

    func fetchAllItems() -> [CustomObject] { 
     // Your code here 
    } 

    func fetchItem(for id: String) -> CustomObject? { 
     // Your code here 
    } 
} 

Тогда в тестировании:

class TestMockClass: MockableProtocol { 
    func deleteItem(_ itemId: String) -> Bool { 
     // Your code here 
    } 

    func fetchAllItems() -> [CustomObject] { 
     // Your code here 
    } 

    func fetchItem(for id: String) -> CustomObject? { 
     // Your code here 
    } 
}