2016-06-04 2 views
0


저는 신속한 작업에 익숙하지 않습니다. 플레이어를 배열에 추가하고 다시 시작하는 경우 상위 5 명이 이름과 점수를 포함하는 게임을 만들려고합니다. 게임은 선수를 "삭제", 그래서, 그것은 코드가 무엇인지에 상관없이 작동하지 않습니다 (난 그냥 5 문자열과 5 개 정수를 저장해야합니다) NSUserDefaults를 사용하는 것을 시도하고있다 :NSUserDefaults를 사용하여 객체의 배열을 저장합니다.

class scoreController: UITableViewController { 

    var playersArray:[Player] = [Player]() 

    var nameFromGame = "" //name from game vc 
    var timeFromGame = 0 //time from game vc 

    let tmpPlayer = Player(playerName: "", scoreTime: 0) 
    let playerDefaults = NSUserDefaults.standardUserDefaults() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let player1 = Player(playerName: "Bil", scoreTime: 50) 
     let player2 = Player(playerName: "Bob", scoreTime: 100) 


     playersArray.append(player1) 
     playersArray.append(player2) 

     tmpPlayer.playerName = nameFromGame 
     tmpPlayer.scoreTime = timeFromGame 
     playersArray.append(tmpPlayer) 

     playerDefaults.setObject(playersArray[11], forKey: "players") 

      print(playersArray) 
     } 
    } 

I 지금은 이것을 저장하려고 시도하고 있으며 충돌이 발생합니다. 왜 그 이유를 알고 있습니까? 또한 데이터를 저장할 수 있도록 어떻게 내 애플 리케이션 에이 저장할 수 있습니까?

감사합니다.

답변

1

플레이어 클래스는 NSCoding을 준수해야하는이 답변을 확인하고 보관하여 플레이어 배열의 데이터를 저장하는 데 필요한 데이터를 추출 할 때 그것을 보관 해제.

등급 :

class Player: NSObject, NSCoding { 
    var playerName: String 
    var scoreTime: Int 

    init(playerName: String, scoreTime: Int) { 
     self.playerName = playerName 
     self.scoreTime = scoreTime 
    } 

    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeInteger(scoreTime, forKey: "score_time") 
     aCoder.encodeObject(playerName, forKey: "player_name") 
    } 

    required convenience init?(coder decoder: NSCoder) { 
     guard let playerName = decoder.decodeObjectForKey("player_name") as? String else { 
      return nil 
     } 
     self.init(playerName: playerName, scoreTime: decoder.decodeIntegerForKey("score_time")) 
    } 
} 

NSUserdefaults & 보관/보관 취소 :이 도움이

let player1 = Player(playerName: "Bil", scoreTime: 50) 
    let player2 = Player(playerName: "Bob", scoreTime: 100) 

    let playersArray = [player1, player2] 
    let playersData = NSKeyedArchiver.archivedDataWithRootObject(playersArray) 

    let defaults = NSUserDefaults.standardUserDefaults() 
    defaults.setObject(playersData, forKey: "players") 
    defaults.synchronize() 

    if let playersArrayData = defaults.objectForKey("players") as? NSData { 
     let unarchivedPlayers = NSKeyedUnarchiver.unarchiveObjectWithData(playersArrayData) as! [Player] 
     print(unarchivedPlayers) 
    } 

희망이 귀하의 질문을 해결되는지 대답까지 - 투표를 선택하는 것을 기억하십시오.

0

당신은 에 필요

playerDefaults.synchronize() 

는 기본값에 데이터를 저장하기 위해 호출 할 수 있습니다.

EDIT
facumenzella에서 말한 것처럼 다른 문제는 기본값으로 맞춤 클래스 개체를 저장하는 것입니다. 이를 해결하려면 사용자 정의 플레이어 클래스에 데이터로 변환하는 방법을 알려주는 메서드를 구현해야합니다. 그런 다음 객체를 기본값으로 저장하기 전에 직렬화해야합니다.

+0

나는 그것을 시도했다 : 예상 선언 – Coder123

+0

아니, 당신은 필요하지 않습니다, 방법은 운영 체제에 의해 정기적으로 호출됩니다. – vadian

+0

그러나 기본값을 설정 한 직후 기본값에 액세스하는 경우 변경 후 동기화해야합니다. 또한 앱이 사용자에 의해 중단되거나 중지 될 가능성이 항상 있습니다.이 경우 기간 동기화가 발생하지 않을 수 있습니다. – milesper

2

플레이어 개체가 여기에서 문제 일 수 있습니다. 당신은 당신의 플레이어 클래스의 두 가지 방법을 구현해야합니다 (난 더 신속 마스터가 아니야하지만 probaby 같은 실수) :

- (void)encodeWithCoder:(NSCoder *)encoder; 
- (id)initWithCoder:(NSCoder *)decoder; 

당신을 위해 일해야한다고. 도움이되기를 바랍니다 !!

PD : How to store custom objects in NSUserDefaults

+0

나는 그것들이 객관적인 C 방법이라고 생각한다. 당신은 빠른 것들을 압니까? – Coder123

+1

여기에 ... https : //developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/#//apple_ref/occ/intfm/NSCoding/encodeWithCoder : 도움이 되었으면합니다! – facumenzella