2015-01-03 7 views
2

Когда я запускаю программу ниже, он вызывает ошибку сегментации. Не могли бы вы помочь мне понять, почему? СпасибоКласс Swift: эталонный цикл

class Animal:NSObject{ 
    var name:String! 
    var age:UInt! 

    weak var spouse:Animal? 
    init(name:String,age:UInt){ 
     self.name=name 
     self.age=age 
    } 

    func description() ->String{ //to become printable 
     return "name= \(name) and age=\(age) spouse=\(spouse)" 
    } 
} 


let dog=Animal(name:"Lucky",age:3) 
let cat=Animal(name:"Branson",age:4) 
dog.spouse=cat 
cat.spouse=dog //It doesnt crash if I comment this line out 
println(dog) 

ответ

4

Проблема заключается в бесконечной рекурсии в вашей печати. После того, как вы настроите полный цикл, чтобы распечатать животное, вы печатаете своего супруга, который печатает своего супруга, который печатает своего супруга и т. Д. Навсегда, пока не закончите пространство стека и не сработает.

Вам нужно сломать, что распечатав супруг животного, не вызывая полную распечатку этого животного, что-то вроде этого:

class Animal: NSObject { 
    // you should avoid using implicitly unwrapped optionals 
    // unless you absolutely have to for a specific reason that 
    // doesn’t appear to apply here (so remove the !s) 
    var name: String 
    var age: UInt 
    weak var spouse: Animal? 

    init(name: String, age: UInt) { 
     self.name = name 
     self.age = age 
    } 
} 

// to make something printable, you need to conform 
// to the Printable protocol 
extension Animal: Printable { 
    // And make description is a var rather than a function 
    override var description: String { 
     let spousal_status = spouse?.name ?? "None" 
     return "name=\(name) and age=\(age), spouse=\(spousal_status)" 
    } 
} 


let dog = Animal(name: "Lucky", age: 3) 
let cat = Animal(name: "Branson", age: 4) 
dog.spouse = cat 
dog.description 
cat.spouse = dog 
println(dog) // Prints name=Lucky and age=3, spouse=Branson 

Примечания, вы должны реализовать Printable полностью с протоколом и варом, чтобы избежать эта проблема, в противном случае вы получите реализацию по умолчанию, которая по-прежнему будет сталкиваться с этой проблемой.

кстати, Swift стиль конвенция положить пространства между вещами как =, -> до { и т.д. (а на самом деле вы можете иногда вызывать проблемы при компиляции, если вы этого не сделаете). Жюри все еще на a: b против a:b, хотя я считаю, что последнее немного сложнее читать.

+0

спасибо. Вчера я выпустил свою ошибку и смог исправить ее в своем коде. Поистине оцените ваши отзывы. –

+0

Добро пожаловать. Просто наконечник переполнения стека - способ поблагодарить кого-то, кто хорошо отвечает на ваш вопрос, - это принять ответ. Это помогает другим понять, что ответ дал ответ на вопрос (для вас, во всяком случае, это не значит, что ответ полностью правильный :) –

0

Ваш код вызывает переполнение стека. Метод description содержит описание spouse, которое в свою очередь инициирует описание его spouse и т. Д. В бесконечном цикле. Попробуйте следующее:

func description() -> String { 
    return "name= \(name) and age=\(age) spouse=\(spouse?.name)" 
} 
Смежные вопросы