swift - 不工作的代表
问题描述
我刚开始使用委托和协议,我认为它非常有用。在我的项目中,当我尝试委托给 ViewController 时,它工作得很好,因为它不适用于我创建的其他类。我不明白为什么。我尝试将数据从类 ServerArtNet 传输到类 FixtureControl。但它不起作用。你知道为什么吗?
服务器艺术网
protocol ArtNetDelegate: class {
func receivedFixtureControll(intS: Float, StrobeS:Float, Red: Float, Green: Float, Blue: Float)
}
class ServerArtNet: NSObject {
weak var delegate:ArtNetDelegate?
let serverUDP = ServerUDP()
func artNetReceive (data:Data) {
let DMX_Universe_Bytes: [UInt8] = [DMX_Universe, 0]
var received = [UInt8]()
received.append(contentsOf: data)
if (received.count > 17) {
let number_of_received_chanel = (UInt16(received[17]<<8) + UInt16(received[16]))
if (received[0...6] == ArtNetHead[0...6]) && (received[7...11] == OpOutput[0...4]) && (received[14...15] == DMX_Universe_Bytes[0...1]) && number_of_received_chanel>0 {
let intensityScreen:Float = received[18].fromDMX()
let shutter:Float = received[19].fromDMX()
let red:Float = received[20].fromDMX()
let green:Float = received[21].fromDMX()
let blue:Float = received[22].fromDMX()
delegate?.receivedFixtureControll(intS:intensityScreen,StrobeS:shutter, Red: red, Green: green, Blue: blue)
}
}
}
}
夹具控制
import UIKit
class FixtureControll: NSObject {
let serverArtNet = ServerArtNet()
override init() {
super.init()
serverArtNet.delegate! = self
}
func Fixture(intS: Float, strobS:Float, red:Float, green:Float, blue:Float) {
// Working with data
}
}
extension FixtureControll: ArtNetDelegate {
func receivedFixtureControll(intS: Float, StrobeS:Float, Red: Float, Green: Float, Blue: Float) {
Fixture(intS: intS, strobS: StrobeS, red: Red, green: Green, blue: Blue)
}
}
服务器UDP
import UIKit
import CocoaAsyncSocket
protocol ServerUDPDelegate: class {
func receiveData(data: Data, address: String)
}
class ServerUDP: NSObject, GCDAsyncUdpSocketDelegate {
weak var delegate: ServerUDPDelegate?
let IP = "255.255.255.255"
let destinationIP = "255.255.255.255"
let PORT:UInt16 = 6454
var socket:GCDAsyncUdpSocket!
override init() {
super.init()
setupConnection()
}
func setupConnection(){
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)
do {
try socket.bind(toPort: PORT)
}
catch {
print("Binding error: ", error.localizedDescription)
}
do {
try socket.beginReceiving()
}
catch {
print("Connecting error: ", error.localizedDescription)
}
do {
try socket.enableBroadcast(true)
}
catch {
print("brodcust error: ", error.localizedDescription)
}
}
func StopServer() {
socket.close()
}
// Receiving data from port
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext withFilterContex: Any?) {
// print("DID RECEIVE DATA")
// Convert NSData to string to get Address info
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
do {
try address.withUnsafeBytes { (pointer:UnsafePointer<sockaddr>) -> Void in
guard getnameinfo(pointer, socklen_t(address.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else {
throw NSError(domain: "domain", code: 0, userInfo: ["error":"unable to get ip address"])
}
}
} catch {
print(error)
return
}
let senderAddress = String(cString:hostname)
delegate?.receiveData(data: data, address: senderAddress)
}
}
扩展
extension ViewController: ServerUDPDelegate {
func receiveData(data: Data, address: String) {
serverArtNet.artNetReceive(data: data)
}
}
视图控制器
import UIKit
import AVFoundation
import AudioToolbox
class ViewController: UIViewController{
let serverUDP = ServerUDP()
var ToolbarAppeare = false
@IBAction func InfoButton(_ sender: UIBarButtonItem) {
self.performSegue(withIdentifier: "Information", sender:sender)
}
@IBAction func TouchTap(_ sender: UITapGestureRecognizer) {
if sender.state == .ended {
ToolbarAppeare = !ToolbarAppeare
self.navigationController?.setNavigationBarHidden(ToolbarAppeare, animated: true)
}
}
override var preferredStatusBarStyle : UIStatusBarStyle {
return .lightContent
}
override var prefersStatusBarHidden: Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
serverUDP.delegate = self
}
func applicationWillTerminate(application: UIApplication) {
serverUDP.StopServer()
}
func UIColorSet (Red:Float, Green:Float, Blue:Float, Alpha:Float) {
self.view.backgroundColor = UIColor(red: CGFloat(Red), green: CGFloat(Green), blue: CGFloat(Blue), alpha: CGFloat(Alpha))
}
}
解决方案
正如我在评论中所写,您实例化了太多实例。这是清除此类不需要的实例创建的示例。
服务器艺术网
protocol ArtNetDelegate: class {
func receivedFixtureControll(intS: Float, strobeS: Float, red: Float, green: Float, blue: Float)
}
class ServerArtNet: NSObject, ServerUDPDelegate {
weak var delegate: ArtNetDelegate?
let serverUDP: ServerUDP
override init() {
serverUDP = ServerUDP() //### Instatiate a new `ServerUDP` dedicated for this instance
super.init()
serverUDP.delegate = self
}
//### This class should manage all lower level events
func receiveData(data:Data, address: String) {
let DMX_Universe_Bytes: [UInt8] = [DMX_Universe, 0]
var received = [UInt8]()
received.append(contentsOf: data)
if (received.count > 17) {
let number_of_received_chanel = (UInt16(received[17]<<8) + UInt16(received[16]))
if (received[0...6] == ArtNetHead[0...6]) && (received[7...11] == OpOutput[0...4]) && (received[14...15] == DMX_Universe_Bytes[0...1]) && number_of_received_chanel>0 {
let intensityScreen:Float = received[18].fromDMX()
let shutter:Float = received[19].fromDMX()
let red:Float = received[20].fromDMX()
let green:Float = received[21].fromDMX()
let blue:Float = received[22].fromDMX()
delegate?.receivedFixtureControll(intS:intensityScreen, strobeS: shutter, red: red, green: green, blue: blue)
}
}
}
func stopServer() {
serverUDP.stopServer()
}
}
这个类应该负责像ServerUDP
. 所以,我让这个类符合ServerUDPDelegate
.
夹具控制
class FixtureControll {
//### Do NOT instantiate a new `ServerArtNet` here.
func fixture(intS: Float, strobeS: Float, red: Float, green: Float, blue: Float) {
// Working with data
}
}
在我看来,这个类的每个实例都不需要有自己的ServerArtNet
. 删除它。
服务器UDP
protocol ServerUDPDelegate: class {
func receiveData(data: Data, address: String)
}
class ServerUDP: NSObject, GCDAsyncUdpSocketDelegate {
weak var delegate: ServerUDPDelegate?
let IP = "255.255.255.255"
let destinationIP = "255.255.255.255"
let port: UInt16 = 6454
var socket: GCDAsyncUdpSocket!
override init() {
super.init()
setupConnection()
}
func setupConnection(){
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)
do {
try socket.bind(toPort: port)
}
catch {
print("Binding error: ", error.localizedDescription)
}
do {
try socket.beginReceiving()
}
catch {
print("Connecting error: ", error.localizedDescription)
}
do {
try socket.enableBroadcast(true)
}
catch {
print("brodcust error: ", error.localizedDescription)
}
}
func stopServer() {
socket.close()
}
// Receiving data from port
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext withFilterContex: Any?) {
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
do {
try address.withUnsafeBytes { (sockadrPtr: UnsafePointer<sockaddr>) -> Void in
guard getnameinfo(sockadrPtr, socklen_t(address.count), &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 else {
throw NSError(domain: "domain", code: 0, userInfo: ["error":"unable to get ip address"])
}
}
} catch {
print(error)
return
}
let senderAddress = String(cString: hostname)
delegate?.receiveData(data: data, address: senderAddress)
}
}
只是重命名了一些标识符以遵循 Swift 约定。
ViewController 及其扩展
class ViewController: UIViewController {
var serverArtNet: ServerArtNet!
var toolbarAppeare = false
@IBAction func InfoButton(_ sender: UIBarButtonItem) {
self.performSegue(withIdentifier: "Information", sender:sender)
}
@IBAction func TouchTap(_ sender: UITapGestureRecognizer) {
if sender.state == .ended {
toolbarAppeare = !toolbarAppeare // You can use `toolbarAppeare.toggle()` in Swift 4.2
self.navigationController?.setNavigationBarHidden(toolbarAppeare, animated: true)
}
}
override var preferredStatusBarStyle : UIStatusBarStyle {
return .lightContent
}
override var prefersStatusBarHidden: Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
serverArtNet = ServerArtNet()
serverArtNet.delegate = self
}
func applicationWillTerminate(application: UIApplication) {
//### Do NOT access lower level classes (`ServerUDP`) directly.
serverArtNet.stopServer()
}
func uiColorSet(red:Float, green:Float, blue:Float, alpha:Float) {
self.view.backgroundColor = UIColor(red: CGFloat(red), green: CGFloat(green), blue: CGFloat(blue), alpha: CGFloat(alpha))
}
}
extension ViewController: ArtNetDelegate {
func receivedFixtureControll(intS: Float, strobeS: Float, red: Float, green: Float, blue: Float) {
let fixtureControl = FixtureControll()
fixtureControl.fixture(intS: intS, strobeS: strobeS, red: red, green: green, blue: blue)
}
}
这个类应该负责delegate
的ServerArtNet
。
一般来说,你不应该声明类似的属性let propName = ClassName()
,除非你有明确的意图来创建一个新的实例。
推荐阅读
- swift - 我可以从自定义视图类更改 NavigationController 设置吗
- swiftui - onTapGesture 与其他视图结合的 SwiftUI 错误或代码问题?
- php - 在 PHP 中确保“唯一”session_id 的算法
- python - 如何提高 API 服务器性能?
- python-3.x - tkinter 框架中有多少行/列?
- python - 使用 pandas read_html() 时遇到问题:ValueError
- c# - NHibernate 正在生成我不正确的 indetity 列
- shopify - 如何在没有会话的情况下在 Shopify 应用上生成访问令牌
- r - 在R中基于时间间隔合并两个数据集
- python - 获取正值的总和和负值的总和