2015-10-26 2 views
0

У меня есть класс, который выполнит поиск. После завершения я хочу, чтобы класс поиска передавал результаты, к которым когда-либо выполнял поиск экземпляр (другого класса). Мое мышление состояло в том, чтобы передать ссылку на класс, который создает экземпляр класса поиска и использует эту ссылку для вызова функции. Вот основной пример того, что я пытаюсь сделать. Как я могу заставить это работать, или есть другой/лучший способ?Swift - передать ссылку на класс

Поиск Класс (Я пробовал AnyObject и UITableViewContoller):

class SearchClass : NSObject, NSURLConnectionDelegate, NSURLConnectionDataDelegate { 
    var callingClass : AnyObject? = nil //To store reference to the "other" class 
    var searchResults : [[String : AnyObject]]? = nil 

    init(callingClass: AnyObject) { //I don't know the name of the ViewController class which will instantiates this as it will be called by several different classes 
     self.callingClass = callingClass 
    } 

    func startSearch(searchString: String) { 
     //NSURLConnection etc 
    } 

    func connectionDidFinishLoading(connection: NSURLConnection) { 
     //more code 
     searchResults = ... 
     callingClass!.searchCompleted(searchResults) //Pass the search results back to the class instance which started the search 
    } 
} 

Другие Классы:

class RandomViewController : UITableViewController { 

    //The casting on the next line fails 
    let Searcher = SearchClass(callingClass: self as! UITableViewController) //OR AnyObject 

    func randomFunction() { 
     searcher.startSearch("search query") 
    } 

    func searchComplete(searchResults: [[String : AnyObject]]) { 
     self.searchResults = searchResults 
     tableView.reloadData() 
    } 
} 

ответ

1

Вы можете добавить параметр укупорочного вашей startSearch функции в поисковой классе:

typealias SearchResultHandler = (result: [String : AnyObject]) ->() 

func startSearch(query: String, resultHandler: SearchResultHandler) { 
    // send the search request and in the completion handler of the request call your result handler: 
    resultHandler(result: searchResult) 
} 

Что вы тогда могли бы позвонить из любого класса:

let searcher = SearchClass() 
searcher.startSearch("query") { (result) ->() in 
    self.searchResults = results 
    tableView.reloadData() 
} 
+0

Это работает, спасибо. Похоже, что вызов startSearch будет ждать возвращения результата. Если по какой-то причине поиск занял некоторое время, чтобы завершить, это приведет к зависанию пользовательского интерфейса? – Daniel

+0

Да, вы должны выполнить поиск асинхронно в фоновом режиме и выполнить закрытие основного потока при завершении поиска. – joern

+0

Большинство фреймворков предлагают завершениеHandler при отправке запроса. Таким образом, запрос выполняется асинхронно. Все, что вам нужно сделать, это вызвать «resultHandler» в методе завершенияHandler метода запроса. – joern

0

Вы можете использовать дженерики, когда вы не знаете, что класс будет:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html

Однако ....

Это похоже на то, что вы должны использовать протокол/делегаты.

// NOTE: weak references must be class type 
protocol SearchClassDelegate: class { 
    func searchComplete(results: [[String: AnyObject]?]) 
} 

// This is where you define T as the generic class 
class SearchClass { 

    weak var delegate: SearchClassDelegate? // This is your "callingClass" 
    // NOTE: make sure it's weak 

    // ... 

    func connectionDidFinishLoading() { 
     // ... 
     self.delegate?.searchComplete(results) 
    } 
} 

// Set to the delegate 
class ViewController: UIViewController, SearchClassDelegate { 

    // ... 
    // Make sure you set the delegate 

    // Here is where you implement this function 
    func searchComplete(results: [[String : AnyObject]?]) { 
     // Do whatever 
     // ...reloadData() etc. 
    } 

}