2016-04-01 18 views
1

üzerinden tüm bir yapının kontrol edilmesi GameKit kullanarak bir Multiplayer Swift (XCode 7.3/iOS 9.2) oyun üzerinde çalışıyorum.GKMatchDelegate didReceiveData

GameKit aracılığıyla gönderilen bilgiler olarak özel bir yapı kullanıyorum. Yapının kopyası aşağıdadır. '(: GKMatch, didReceiveData verilerine: NSData, fromRemotePlayer oyuncu: GKPlayer maç) maçı' frustrationNetworkMessage bir dize enum & Kart

struct frustrationNetworkMessage { 
var messageType : FrustrationNetworkMessageType 
var cards : [Card] 
var actingPlayer : String 

init(messageType : FrustrationNetworkMessageType, cards : [Card], actingPlayer : String) { 
    self.messageType = messageType 
    self.cards = cards 
    self.actingPlayer = actingPlayer 
} 

Sorunum içindedir (gerekirse kod gönderebilirsiniz) ayrı sınıftır olduğunu yöntem. Bu bazı veriler alındıktan sonra çağrılan dışarı çalıştık:

private var receivedData : NSMutableData 

func decode<T>(data: NSData) -> T { 
    let pointer = UnsafeMutablePointer<T>.alloc(sizeof(T.Type)) 
    data.getBytes(pointer, length: sizeof(T)) 
    return pointer.move() 
} 

func match(match: GKMatch, didReceiveData data: NSData, fromRemotePlayer player: GKPlayer) { 
    print("Match/did receive data: size of data - \(sizeofValue(data))") 
    receivedData.appendData(data) 
    if let receivedNetworkMessage : frustrationNetworkMessage = decode(receivedData) { 
     print("Match/did receive data: \(receivedNetworkMessage.messageDetails())") 

Ben buna bir kısmını erişmeye çalışıyor şikayet anlamak EXC_BAD_ACCESS (nihai baskı deyimi de çöküyor Yukarıdaki kodu çalıştırdığınızda alınmamış olan yapı). Mesaj türü: actingPlayer ile startNewGame: G: 118279601 & kart sayısı: 1 - mesaj boyutu: 40

mesaj uzunluğu ilk kez>sendNetworkMessage - gönderilen en

Mesaj özeti: Bir örnek olarak

match didReceiveData çağrıldı ->Eşleşme/veri alma: veri boyutu - 8

Tüm yapının üzerine etki etmeden önce kontrol ettiğimi nasıl kontrol edebilirim? Yapıyı bir uzunluk alanı içerecek şekilde güncellemeyi düşünmüştüm (teoride her zaman bunu bir seferde almalıyım - böylece paket uzunluğunu kontrol etmek için kullanabilirdim).

cevap

0

Veri yapınızı sürekli olarak kontrol etmek için böyle bir arka plan işlemini kullanabilirsiniz.

newQueue = NSOperationQueue()

let operation2 = NSBlockOperation(block: { 


    }) 

operation2.completionBlock = { 
    print("Operation 2 completed") 
} 

let operation1 = NSBlockOperation(block: { 


    }) 

operation1.completionBlock = { 

    self.newQueue.addOperation(operation2) 
} 

operation1.qualityOfService = .UserInitiated 
newQueue.addOperation(operation1) 
} 

değişkenler için başlangıç ​​ve daha sonra uzunluğunu kontrol; Bu, kilitlenecek/durduracak.

0

ben her dakika için bir cevap (sorun şimdi kodda başka bir yerde taşındı) buldum

Ben deneme yoluyla bir hata (ve takip okuma birçok) buldum Ne
struct frustrationNetworkMessage { 
var messageType : FrustrationNetworkMessageType 
var card : Card 
var actingPlayer : String 

init(messageType : FrustrationNetworkMessageType, card : Card, actingPlayer : String) { 
    self.messageType = messageType 
    self.card = card 
    self.actingPlayer = actingPlayer 
} 

init(data : NSData) { 
    let messageTypeLength = sizeofValue(FrustrationNetworkMessageType) 
    let cardLength = sizeofValue(Card) 

    let messageTypeRange = NSMakeRange(0, messageTypeLength) 
    let cardLengthRange = NSMakeRange(messageTypeLength, messageTypeLength + cardLength) 
    let actingPlayerRange = NSMakeRange(messageTypeLength + cardLength, data.length) 

    self.messageType = .didDiscardCard 
    self.card = Card.emptyCard() 

    data.getBytes(&self.messageType, range: messageTypeRange) 
    data.getBytes(&self.card, range: cardLengthRange) 
    let actingPlayerData = data.subdataWithRange(actingPlayerRange) 
    self.actingPlayer = NSString(data: actingPlayerData, encoding: NSUTF8StringEncoding) as! String 
} 

func archive()->NSData { 
    var localMessageType = messageType.rawValue 
    var localCard = card 

    let returnValue = NSMutableData(bytes: &localMessageType, length: sizeofValue(self.messageType.rawValue)) 
    returnValue.appendData(NSData(bytes: &localCard, length: sizeofValue(self.card))) 
    returnValue.appendData(actingPlayer.dataUsingEncoding(NSUTF8StringEncoding)!) 
    return returnValue 
} 

:

  1. didReceiveData sadece bütün bir paket aldığında denilen olsun görünüyor

    maç

  2. (böylece alıcı kısmi verileri işlemek için gerekmez) önlemek mümkün enc sınıf veri türlerini NSData olarak biçimlendirmek (yalnızca yerel bir adresi kodladığımı kazma yoluyla, yerel olarak geçiyorsa iyi çalışıyor - ağ üzerinde çok fazla değil). Tüm veri türlerime, temel olanları (tüm numaralar artık UInt8 tipi) veya yapıları olarak kapatın.