我想trimmedText为UITextViewand创建一个属性UITextField。这是我所做的:
protocol TrimmedTextSupporting: class {
var _text: String? { get }
var trimmedText: String { get }
}
extension TrimmedTextSupporting {
var trimmedText: String {
let text = self._text ?? ""
return text.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
}
}
extension UITextField: TrimmedTextSupporting {
var _text: String? {
return self.text
}
}
extension UITextView: TrimmedTextSupporting {
var _text: String? {
return self.text
}
}
Run Code Online (Sandbox Code Playgroud)
我需要_text财产,因为text被声明为String?inUITextField和 as String!inUITextView (whyyyy?!>_<)。现在我想隐藏这个属性以避免混淆 API。 …
如何对实现协议的类进行扩展?
类似的东西:
protocol proto {
func hey()
}
Run Code Online (Sandbox Code Playgroud)
以及符合以下条件的类proto:
Class MyClass: UIViewController, proto {
func hey() {
print("Hey!")
}
}
Run Code Online (Sandbox Code Playgroud)
然后是该类的扩展,如下所示:
extension UIViewController where Self:proto {
func test() {
print("I'm extended!")
}
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以打电话self.test()了MyClass。
谢谢。
如果我有两个协议,其关联类型恰好相同,例如
protocol Read {
associatedtype Element
func read() -> Element
}
protocol Write {
associatedtype Element
func write(a: Element)
}
Run Code Online (Sandbox Code Playgroud)
然后我想要一个类来读取整数并将字符串写入:
class ReadWrite: Read, Write {
func read() -> Int {
return 5
}
func write(a: String) {
print("writing \(a)")
}
}
Run Code Online (Sandbox Code Playgroud)
但编译器抱怨并建议更改String为Int. 理想情况下,应该推断类型,或者至少在我显式声明时编译
associatedtype Read.Element = Int
associatedtype Write.Element = String
Run Code Online (Sandbox Code Playgroud)
之内ReadWrite。有解决办法吗?
受此问题启发的解决方法是创建两个辅助协议
protocol ReadInt: Read {
associatedtype Element = Int
}
protocol WriteString: Write {
associatedtype Element = String
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用泛型在 Swift 3 中完成面向协议的编程。这还不完全支持吗?我将在下面向您展示我想做但不会编译的内容。我在这里错过了什么吗?我的目标是能够使用面向协议的编程来执行依赖注入,目的是在我的单元测试中轻松模拟这些结构。
protocol ZombieServiceProtocol {
func fetchZombies()
var zombieRepository: RepositoryProtocol<Zombie> { get set }
}
struct ZombieService: ZombieServiceProtocol {
var zombieRepository: RepositoryProtocol<Zombie>
init(zombieRepository: RepositoryProtocol<Zombie>) {
self.zombieRepository = zombieRepository
}
func fetchZombies() {
self.zombieRepository.deleteAll()
self.createFakeZombies()
}
private func createFakeZombies() {
for index in 1...100 {
let zombie = Zombie(id: index, name: "Zombie \(index)")
self.zombieRepository.insert(zombie)
}
}
}
Run Code Online (Sandbox Code Playgroud)
Zombie 类如下所示:
public struct Zombie: Persistable {
var id: Int
let name: String?
init(id: Int, name: String?) {
self.id = id
self.name …Run Code Online (Sandbox Code Playgroud) 我不得不在 Swift 中使用类型擦除几次,但它总是涉及通用协议。在这种情况下,它涉及通用枚举和通用协议,我被难住了。
这是我的通用枚举和通用协议以及必要的扩展:
enum UIState<T> {
case Loading
case Success([T])
case Failure(ErrorType)
}
protocol ModelsDelegate: class {
associatedtype Model
var state: UIState<[Model]> { get set }
}
extension ModelsDelegate {
func getNewState(state: UIState<[Model]>) -> UIState<[Model]> {
return state
}
func setNewState(models: UIState<[Model]>) {
state = models
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的类型擦除泛型类:
class AnyModelsDelegate<T>: ModelsDelegate {
var state: UIState<[T]> {
get { return _getNewState(UIState<[T]>) } // Error #1
set { _setNewState(newValue) }
}
private let _getNewState: ((UIState<[T]>) -> UIState<[T]>)
private …Run Code Online (Sandbox Code Playgroud) 假设下面定义了一个协议:
protocol Identifiable {
static var identifier: String { get }
}
extension Identifiable {
static var identifier: String { return "Default Id" }
}
Run Code Online (Sandbox Code Playgroud)
引用静态变量的最佳方法是什么?下面的示例说明了两种访问变量的方法。有什么区别,type(of:)更好吗?
func work<I: Identifiable>(on identifiable: I) {
let identifier: String = I.identifier
print("from Protocol: \(identifier)")
let identiferFromType: String = type(of: identifiable).identifier
print("using type(of:): \(identiferFromType)")
}
struct Thing: Identifiable {
static var identifier: String { return "Thing" }
}
work(on: Thing())
Run Code Online (Sandbox Code Playgroud) 当我的应用程序第一次启动时,我做了一些第一次设置配置,它使用 CoreData API 和来自 JSON 文档的数据为我的 SQLLite 数据库做种。
为此,我首先从核心数据堆栈获取对托管对象上下文的引用,然后调用执行 JSON 配置的方法。然后我打电话:
....(JSON conversion)....
context.perform {
_ = Exercise.insert(into: context, name: exerciseName, category: categoryNumber, equipment: equipment, skill: "", primaryMuscle: primaryMuscle, otherMuscles: otherMuscles, info: exerciseDescription, image1: exerciseImage1, image2: exerciseImage2)
}
Run Code Online (Sandbox Code Playgroud)
在我循环遍历 JSON 对象时的每次迭代中,它都会保留每个对象。
插入对象的方法是这样的:
public static func insert(into context: NSManagedObjectContext, name: String, category: Int16, equipment: String?, skill: String?, primaryMuscle: String?, otherMuscles: String?, info: String?, image1: String?, image2: String?) -> Exercise {
let exercise: Exercise = context.insertObject()
exercise.name = name
exercise.category = category …Run Code Online (Sandbox Code Playgroud) 我有一些 UT 的问题,我正在尝试快速编写
我有一个带有“做事”扩展名的协议:
protocol MyProtocol: class
{
var myVar: SomeClass { get }
func doStuff(identifier: String) -> Bool
}
extension MyProtocol
{
func doStuff(identifier: String) -> Bool {
return true
}
}
Run Code Online (Sandbox Code Playgroud)
然后是一个实现我的协议的类
final class MyClass: MyProtocol {
}
Run Code Online (Sandbox Code Playgroud)
这个类有一个扩展,它实现了另一个协议,它有一个我应该测试的方法
public protocol MyOtherProtocol: class {
func methodToTest() -> Bool
}
extension MyClass: MyOtherProtocol {
public func methodToTest() {
if doStuff() {
return doSomething()
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个设置有没有办法模拟 doStuff 方法?
我只是在阅读有关协议初始值设定项要求的 Apple Swift 4 文档并在协议扩展中提供默认实现。
import UIKit
protocol Protocol {
init()
}
extension Protocol {
init() {
print("SDf")
self.init() // Line 1
// Compiler error occured if this is omitted
//"'self.init' isn't called on all paths before returning from initializer"
}
}
struct Structure: Protocol {
init(string: String) {
}
}
Structure() // Line 2
Run Code Online (Sandbox Code Playgroud)
现在如您所见,执行将进入循环,因为默认情况下该结构没有实现 for init(),因此将调用提供的协议 init 并再次调用自身,因此进入无限循环.
现在,知道了这一点,如果我删除第 1 行,编译器就会给出错误。
Q. 为什么强制我self.init()在1号线使用,如何摆脱这种情况?
为什么以下代码在#2 处打印“BaseP”?
protocol BaseP { func foo() }
extension BaseP { func foo() { print("BaseP") } }
protocol SubP: BaseP {}
extension SubP { func foo() { print("SubP") } }
class C: SubP {}
let subP1: SubP = C()
subP1.foo() // #1 prints "SubP", fine.
class BaseC: BaseP {}
class SubC: BaseC, SubP {}
let subP2: SubP = SubC()
subP2.foo() // #2 prints "BaseP". why?
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我们调用foo()静态类型为 的SubP引用,引用具有动态类型的对象,该对象是符合 的类SubP。即使它是静态调度,我认为它仍然应该调用SubP.foo(). 为什么在#2 处调用基本协议实现?
另外,为什么继承 from …
swift-protocols ×10
swift ×9
generics ×3
ios ×2
core-data ×1
sqlite ×1
swift2 ×1
unit-testing ×1
xcode ×1