iOS
Երբ և ինչպես է տեղի ունենում չեղարկումը, երբ օգտագործվում է DispatchQueue-ով WorkItem և կանչվում է cancel()?
struct CustomButtonStyleView: View { var body: some View { VStack { Button("Button") { print("Tapped") } } .buttonStyle(CustomButtonStyle()) } } private struct CustomButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .padding() .foregroundColor(.white) .frame(maxWidth: .infinity) .background(Color.red) .clipShape(RoundedRectangle(cornerRadius: 8)) } }
վերջնական դաս Cache<T>: CacheProtocol { func getValue(forKey key: String) -> T? { return storage[key] } func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) { let value = storage[key] completion(value) } } վերջնական դաս CacheTests: XCTestCase { override func setUp() { super.setUp() } func testSetAndGetValue() { let cache = Cache<String>() let key: String = "key" let value: String = "value" cache.setValue(value, forKey: key) XCTAssertEqual(cache.getValue(forKey: key), value) cache.setValue(nil, forKey: key) XCTAssertTrue(cache.getValue(forKey: key) == nil) } func testCompletion() { } } CacheTests.defaultTestSuite.run()
Ներկայացրեք հիշողության մեջ գտնվող կեշի և դիսկի վրա գտնվող կեշի տարբերությունը։
Պատմիր օգտակար Property Wrapper-ների մասին, որոնք օգտագործել ես նախագծում
պրոտոկոլ CacheProtocol { associatedtype Value func setValue(_ value: Value?, forKey key: String) func getValue(forKey key: String) -> Value? func fetchValue(forKey key: String, completion: @escaping (Value?) -> Void) } final class Cache<T>: CacheProtocol { private var storage: [String: T] = [:] func setValue(_ value: T?, forKey key: String) { storage[key] = value } func getValue(forKey key: String) -> T? { return storage[key] } func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) { let value = storage[key] completion(value) } } import XCTest final class CacheTests: XCTestCase { override func setUp() { super.setUp() } func testSetAndGetValue() { let cache = Cache<String>() let key: String = "key" let value: String = "value" cache.setValue(value, forKey: key) XCTAssertEqual(cache.getValue(forKey: key), value) cache.setValue(nil, forKey: key) XCTAssertTrue(cache.getValue(forKey: key) == nil) } } CacheTests.defaultTestSuite.run()
Եթե իրականացնում եք նոր էկրան կամ նոր ֆունկցիա, անմիջապես գրում եք SwiftUI-ով, թե՞ քննարկումներ կան UIKit և SwiftUI ընտրության մասին։
// Գրեք `data`-ն `file` անվամբ ֆայլում: func writeData(_ data: Data, to file: String) { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) try? data.write(to: fileURL) } // Հեռացրեք `file` անվամբ ֆայլը: func remove(file: String) { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) try? FileManager.default.removeItem(at: fileURL) } // Կարդացեք `Data`-ն `file` անվամբ ֆայլից: Եթե ֆայլը չկա, վերադարձնում է `nil`: func readData(from file: String) -> Data? { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) return try? Data(contentsOf: fileURL) } final class DiskCache<T>: CacheProtocol { func setValue(_ value: T?, forKey key: String) { } func getValue(forKey key: String) -> T? { } func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) { } }
Պատմեք ինձ SwiftUI-ի օգտագործման մասին նախագծում — ինչ է քաղաքականությունը, քանի էկրան է գրված SwiftUI-ով
import UIKit պաշտոնական CacheProtocol { associatedtype Value func setValue(_ value: Value?, forKey key: String) func value(forKey key: String) -> Value? func fetchValue(forKey key: String, completion: @escaping (Value?) -> Void) }
Ինչու եք ստեղծել առանձին load և getLastCities մեթոդներ, և ինչ պետք է տեղի ունենա, եթե getLastCities-ը կանչվի տվյալների բեռնումից առաջ?
Ինչպե՞ս կդասավորեիք հայտնաբերված խնդիրների առաջնահերթությունը, եթե նախագիծը պետք է մեկ ժամից արտադրություն անցնի:
import UIKit protocol CacheProtocol { associatedtype Value func setValue(_ value: Value?, forKey key: String) func getValue(forKey key: String) -> Value? func fetchValue(forKey key: String, completion: @escaping (Value?) -> Void) } final class Cache<T>: CacheProtocol { private var storage: [String: T] = [:] private let queue = DispatchQueue(label: "my.queue", attributes: .concurrent) func setValue(_ value: T?, forKey key: String) { queue.sync(flags: .barrier) { storage[key] = value } } func getValue(forKey key: String) -> T? { queue.sync { return storage[key] } } func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) { queue.async { let value = self.storage[key] completion(value) } } }
Ինչպե՞ս եք հասկանում կառուցվածքային համաժամանակությունը Swift-ում: Task.detached արդյո՞ք համապատասխանում է այս հասկացությանը։
Ինչու օգտագործել վերջնական դասը՝ փոխարեն դասի համար, որը իրականացնում է պահեստը?
// Ծառայություն, որը ուղարկում է հարցումներ (get/post), url, հարցման ձևավորում սիմանտիկայի համաձայն (decode/encode)
enum HTTPMethod: String { case post = "POST" } enum Errors: Error { case invalidUrl case invalidQuery case invalidResponse case httpStatus(Int) } protocol MyDecoder { func decode<T: Decodable>(_: _ type: T.Type, from data: Data) throws -> T } final class NetworkService { private let session: URLSession private let encoder = JSONEncoder() private let decoder: MyDecoder init( session: URLSession = .shared, decoder: MyDecoder ) { self.session = session self.decoder = decoder } func request<Response: Decodable, Body: Encodable>( urlString: String, method: HTTPMethod, body: Body? = nil, headers: [String: String] = [:], query: [String: String] = [:] ) async throws -> Response { guard var components = URLComponents(string: urlString) else { throw Errors.invalidUrl } if !query.isEmpty { components.queryItems = query.map { URLQueryItem(name: $0.key, value: $0.value) } } guard let url = components.url else { throw Errors.invalidQuery } var request = URLRequest(url: url)