Xcode 9.2, Swift 4
class AsyncOperation {
typealias NumberOfPendingActions = Int
typealias DispatchQueueOfReturningValue = DispatchQueue
typealias CompleteClosure = ()->()
private let dispatchQueue: DispatchQueue
private var semaphore: DispatchSemaphore
private var numberOfPendingActionsQueue: DispatchQueue
public private(set) var numberOfPendingActions = 0
var whenCompleteAll: (()->())?
init(numberOfSimultaneousActions: Int, dispatchQueueLabel: String) {
dispatchQueue = DispatchQueue(label: dispatchQueueLabel)
semaphore = DispatchSemaphore(value: numberOfSimultaneousActions)
numberOfPendingActionsQueue = DispatchQueue(label: dispatchQueueLabel + "_numberOfPendingActionsQueue")
}
func run(closure: @escaping (@escaping CompleteClosure)->()) {
self.numberOfPendingActionsQueue.sync {
self.numberOfPendingActions += 1
}
dispatchQueue.async {
self.semaphore.wait()
closure {
self.numberOfPendingActionsQueue.sync {
self.numberOfPendingActions -= 1
if self.numberOfPendingActions == 0 {
self.whenCompleteAll?()
}
}
self.semaphore.signal()
}
}
}
}
let asyncOperation = AsyncOperation(numberOfSimultaneousActions: 1, dispatchQueueLabel: "AnyString")
asyncOperation.whenCompleteAll = {
print("All Done")
}
for i in 0...5 {
print("\(i)")
asyncOperation.run{ completeClosure in
// add any (sync/async) code
//..
// Make signal that this closure finished
completeClosure()
}
}
import UIKit
class ViewController: UIViewController {
let asyncOperation = AsyncOperation(numberOfSimultaneousActions: 3, dispatchQueueLabel: "AnyString")
let button = UIButton(frame: CGRect(x: 50, y: 80, width: 100, height: 40))
let label = UILabel(frame: CGRect(x: 180, y: 50, width: 150, height: 100))
var counter = 1
var labelCounter = 0
override func viewDidLoad() {
super.viewDidLoad()
button.setTitle("Button", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
label.text = "\(labelCounter)"
label.numberOfLines = 2
label.textAlignment = .natural
view.addSubview(button)
view.addSubview(label)
}
@objc func buttonTapped() {
//sample1()
sample2()
}
func sample1() {
print("Sample 1")
labelCounter += 1
label.text = "button tapped \(labelCounter) times"
print("Button tapped at: \(Date())")
asyncOperation.whenCompleteAll = {
print("All Done")
}
asyncOperation.run{ completeClosure in
let counter = self.counter
print(" - Loading action \(counter) strat at \(Date())")
self.counter += 1
DispatchQueue.global(qos: .background).async {
sleep(1)
print(" - Loading action \(counter) end at \(Date())")
completeClosure()
}
}
}
func sample2() {
print("Sample 2")
label.text = ""
asyncOperation.whenCompleteAll = {
print("All Done")
}
for i in 0...5 {
asyncOperation.run{ completeClosure in
let counter = self.counter
print(" - Loading action \(counter) strat at \(Date())")
self.counter += 1
DispatchQueue.global(qos: .background).async {
sleep(UInt32(i+i))
print(" - Loading action \(counter) end at \(Date())")
completeClosure()
}
}
}
}
}
Образец 1
Образец 2
// Store the formatted string in 'result'
String result = String.format("%4d", i * j);
// Write the result to standard output
System.out.println( result );
@erickson.
Строки являются неизменными типами. Вы не можете изменить их, только возвратить новые строковые экземпляры.
Из-за этого, "нечто" .format () имеет мало смысла, как это нужно было бы назвать как [1 110]
string newString = "foo".format();
исходные авторы Java (и авторы.NET), решил, что статический метод имел больше смысла в этой ситуации, поскольку Вы не изменяете "нечто", но вместо этого называете способ форматирования и передаете во входной строке.
РЕДАКТИРОВАНИЕ : Heh, этот сайт может иногда быть настолько забавным. Я получил downvoted для упоминания того, что строки являются неизменными типами.
Вот пример того, почему Формат () был бы немым как метод экземпляра. В.NET (и вероятно в Java), Замена () является методом экземпляра.
можно сделать это:
"I Like Wine".Replace("Wine","Beer");
Однако ничего не происходит, потому что Строки неизменны. Замена пытается возвратить новую строку, но она ничему не присвоена.
Это вызывает много общих ошибок новичка как:
// Contrived Example
inputText.Replace(" ","%20");
Снова, ничего не происходит, вместо этого необходимо сделать:
inputText = inputText.Replace(" ","%20");
Теперь, если Вы понимаете, что строки неизменны, который имеет идеальный смысл. Если Вы не делаете, то Вы просто смущены. Надлежащее место для Замены, был бы то, где Формат как статический метод Строки:
inputText = String.Replace(inputText," ", "%20");
Теперь нет никакого вопроса относительно того, что продолжается.
реальный вопрос, почему сделал авторов этих платформ, решают, что нужно быть методом экземпляра и другими помехами? По-моему, оба более изящно выражаются как статические методы, но erickson, кажется, думает, что оба принадлежат как методы экземпляра.
Независимо от Вашего мнения, истина - то, что Вы являетесь менее склонными для создания ошибки с помощью статической версии, и код легче понять (Никакие Скрытые Глюки).
, Конечно, существуют некоторые методы, которые прекрасны как методы экземпляра, берут Строку. Длина ()
int length = "123".Length();
В этой ситуации, ее очевидное мы не пытаемся изменить "123", мы просто осмотр его и возврат его длины... Это - идеальный кандидат на метод экземпляра.
Мои простые правила, например, Методы на Неизменных Объектах: