2017-03-16 1 views
2

사용자 기본값으로 저장된 동일한 오브젝트가 있는지 여부에 따라 오브젝트를 작성하려는 앱이 있습니다. 개체가 발견되면 클래스 init에서이를 감지하고 일찍 리턴하고 싶습니다. 콘솔에서 몇 가지 오류가 있습니다 신속하게 init에서 리턴하는 방법 3

init() { 

    /* There are two possibilities when creating a hero: 
    1. The hero is brand new and needs to be built from scratch 
    2. The hero is loaded from defaults */ 

    // Check to see if there is existing game data: 

    if defaultExistsForGameData() { 
     // This means there is a hero to load and no need to create a new one 
     self = extractHeroFromDefaults() // This just loads from UserDefaults 
     print("Loading hero from defaults with name of: \(hero.heroName).") 

     return self 
    } 

    // These actions are for creating a brand new hero 
    let size = CGSize(width: 32, height: 32) 
    let heroTexture = SKTexture(imageNamed: "hero2.ico") 
    super.init(texture: heroTexture, color: .clear, size: size) 

    self.isUserInteractionEnabled = true 
    self.name = "hero" 

    self.zPosition = 50 

} 

는, 자기 나는이 유효한 패턴이 있는지 알고 싶은 등, 불변 경우, 또는 내가 완전히 복용해야한다 : 이것은 내가 할 노력하고 무엇인가 다른 접근법.

답변

3

Swift (ObjC와 다른)에서 init은 자신과 다른 개체를 반환 할 수 없습니다. 여기에서하려고하는 일을 달성하는 일반적인 방법은 클래스 팩터 리 메서드를 사용하는 것입니다 (다른 개체가 직접 호출하지 못하도록하려면 선택적으로 init으로 지정). 예를 들어

,이 라인을 따라 뭔가 :

class func loadOrCreate() -> Hero { 
    if defaultExistsForGameData() { 
     // This means there is a hero to load and no need to create a new one 
     print("Loading hero from defaults with name of: \(hero.heroName).") 
     return extractHeroFromDefaults() // This just loads from UserDefaults 
    } else { 
     return Hero() 
    } 
} 

private init() { 
    let size = CGSize(width: 32, height: 32) 
    let heroTexture = SKTexture(imageNamed: "hero2.ico") 
    super.init(texture: heroTexture, color: .clear, size: size) 

    self.isUserInteractionEnabled = true 
    self.name = "hero" 

    self.zPosition = 50 
} 

현재 API에 가까운 또 다른 방법이 같은 별도의 (아마도 개인) 지정된 초기화를 만드는 것입니다

:

private init(name: String, zPosition: Int) { 
    let size = CGSize(width: 32, height: 32) 
    let heroTexture = SKTexture(imageNamed: "hero2.ico") 
    super.init(texture: heroTexture, color: .clear, size: size) 

    self.isUserInteractionEnabled = true 
    self.name = name 
    self.zPosition = zPosition 
} 

public convenience init() { 
    let name: String 
    let zPosition: Int 
    if defaultExistsForGameData() { 
     name = defaultName() // Read it out of user defaults 
     zPosition = defaultZPosition 
    } else { 
     name = "hero" 
     zPosition = 50 
    } 
    self.init(name: name, zPosition: zPosition) 
} 

이 방법의 한 가지 문제점은 약간 놀랄 수 있다는 것입니다. 복수 Hero 개체를 만들면 어떤 일이 발생하는지 정확히 알 수 없습니다. loadOrCreate()과 같은 것은 외부 영향이 있다는 것을 분명하게합니다.

+0

감사합니다. 이것이 필자가 필요로하는 분석입니다. 내가 아직 실행중인 한 가지 문제는 사용자 지정 개체를 기본값으로 저장하고 다시로드 할 수 있지만 개체를 ​​만들 때 속성이 모두 기본값이된다는 것입니다. NSCoding과 같은 다른 단계를 수행해야합니까? – zeeple

+0

이것은 사용자 기본값에 어떻게 쓰는지에 따라 다릅니다. 일반적으로 당신의 접근 방식이'NSCoding'을 요구한다면, 그렇게하지 않으면 전혀 작동하지 않을 것입니다. 나는 당신이 실제로 쓰고 있다고 생각하는 것을 실제로 쓰고 있는지 그리고 당신이 읽고있는 것에 가치를 부여하고 있는지 확인합니다. 많은'print' 문이나 중단 점이 여러분의 친구입니다. –

관련 문제