2015-10-26 2 views
0

У моего приложения есть класс MyDevice, который я использую для связи с оборудованием. Это оборудование указывать необязательно, так это переменная экземпляра:Упрощение вложенных, если в swift

var theDevice:MyDevice = nil 

Затем, в приложении, я должен инициализировать устройство (для связи), а затем выполнить самодиагностику, чтобы проверить его доступность и готовность выполнять. Если это не удается, устройство либо недоступно/доступно/не работает.

Вот мой чрезмерно сложный код. Я смотрю, как его упростить.

if let device = self.theDevice 
{ 
    device.initDevice() 

    if (!device.selfTest()) 
    { 
     self.theDevice = nil; 
    } 
} 

Я пытался объединить все тесты с & & в если заявление, но это не удается. Проблема в том, что у меня есть 12 из них для различных устройств в начале функции. Это занимает много места и грязно. Как я могу объединить эти инструкции в Swift?

+0

«объединить все три теста» Я вижу только 2 'if's. Какое третье условие?Кроме того, мне кажется, что «слишком сложно» для меня. Я считаю это очень читаемым. – Arc676

+1

Протокол и функция, которую вы вызываете и передаете каждому устройству, а устройства могут быть в массиве, который вы итерации – Wain

+0

@ Arc676: спасибо. Я изменил текст. Что я имел в виду, так это то, что я должен вызвать initDevice() перед selfTest(). – Adeline

ответ

0

Вы можете использовать ? опциональные цепочки, и объединить if case let сопоставления с образцом и where о

theDevice?.initDevice() 
if case let selfTest? = theDevice?.selfTest() where !selfTest{ 
    theDevice = nil 
} 

Но я бы предпочел if let по желанию разворачивания для удобства чтения.

0

Вы могли бы улучшить это путем initDevice возвращение self, то вы можете сделать следующее:

if case let selfTest? = theDevice?.initDevice().selfTest() where !selfTest { 
    theDevice = nil 
} 

Другим вариантом может быть, чтобы сделать initDevice выполнить selfTest и вернуть его.

Все это предполагает, что код initDevice является вашим кодом, или вы можете так или иначе редактировать его.

Если это не редактируется, вы всегда можете сделать расширение и сделать новый метод в том, что:

extension TheDeviceClass { 

    func initAndTest() -> Bool { 
     initDevice() 
     return selfTest() 
    } 
} 

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

if case let selfTest? = theDevice?.initAndTest() where !selfTest { 
    theDevice = nil 
} 

но это может сделайте его более сложным, чем вы хотели бы. Если вы используете этот код много, подумайте о том, чтобы использовать его другим способом.

0

Я думаю, вы должны изменить свою реализацию MyDevice, чтобы сделать ваш код менее избыточным, указав failable initializer и выполните все проверки внутри него. Таким образом, если сбой инициализации, вы получите нуль и можете просто присвоить его соответствующему свойству другого класса и даже не нужен метод, который проверяет 12 устройств.

class MyDevice { 
    func selfTest() -> Bool { 
    // test 
    return testresult 
    } 

    func initDevice() { 
    // initialization 
    } 

    init?() { 
    self.initDevice() 
    if !self.selfTest() { 
     return nil 
    } 
    } 
} 

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

class SomeClassThatHasTwelveDevices { 
    var theDeviceOne: MyDevice? 
    var theDeviceTwo: MyDevice? 
    var theDeviceThree: MyDevice? 
    var theDeviceFour: MyDevice? 
    var theDeviceFive: MyDevice? 
    var theDeviceSix: MyDevice? 
    var theDeviceSeven: MyDevice? 
    var theDeviceEight: MyDevice? 
    var theDeviceNine: MyDevice? 
    var theDeviceTen: MyDevice? 
    var theDeviceEleven: MyDevice? 
    var theDeviceTwelve: MyDevice? 

    func someMethodThatChecksAllDevices() { 
    let check: (inout MyDevice?) -> Void = { deviceRef in 
     if let device = deviceRef { 
     device.initDevice() 
     if !device.selfTest() { 
      deviceRef = nil 
     } 
     } 
    } 
    check(&theDeviceOne) 
    check(&theDeviceTwo) 
    check(&theDeviceThree) 
    check(&theDeviceFour) 
    check(&theDeviceFive) 
    check(&theDeviceSix) 
    check(&theDeviceSeven) 
    check(&theDeviceEight) 
    check(&theDeviceNine) 
    check(&theDeviceTen) 
    check(&theDeviceEleven) 
    check(&theDeviceTwelve) 
    } 
} 
Смежные вопросы