[swift-users] Initialization Catch-22?

Howard Lovatt howard.lovatt at gmail.com
Tue Sep 26 02:46:33 CDT 2017


I know were you are coming from, but:

  1. In other languages it would be the equivalent of an force unwrapped
optional and you could get a NullPointerException (or worse - core dump).
Using a force unwrapped optional just levels the playing field!

  2. You could make it private(set) which would de-risk the var bit.

  3. See below.

class AssignOnce<T: AnyObject> {
    weak var value: T? = nil { // Use a weak var to avoid a retain cycle.
        willSet {
            guard value == nil else {
                fatalError("Can only be set once.")
            }
        }
    }
}
class InitSelfDependency {
    let dependsUponSelf = AssignOnce<InitSelfDependency>()
    init() {
        dependsUponSelf.value = self
    }
}
let i = InitSelfDependency()
i.dependsUponSelf


On Tue, 26 Sep 2017 at 4:44 pm, Kenny Leung via swift-users <
swift-users at swift.org> wrote:

> Hi Howard.
>
> Yes, this would make it compile, but it still would not solve the issues
> that make it wrong in my mind:
>
> 1. I would have to make it a var, but it should not be mutable.
>
> 2. It’s not optional. Without it, the PDAudioPlayer class could not
> function.
>
> Of course, this is just being stubbornly pedantic about the code,  but the
> whole point of this project is an exercise in pedantry.
>
> -Kenny
>
>
> On Sep 25, 2017, at 10:35 PM, Howard Lovatt <howard.lovatt at gmail.com>
> wrote:
>
> You could try making mQueue a force unwrapped optional or initialize it to
> a failed queue before overwriting on last line of `init`.
>
> On Tue, 26 Sep 2017 at 11:39 am, Kenny Leung via swift-users <
> swift-users at swift.org> wrote:
>
>> Hi Muthu.
>>
>> Thanks for the suggestion.
>>
>> I don’t want to do that because failure to create the AudioQueue should
>> mean failure to create the AudioPlayer itself.
>>
>> -Kenny
>>
>>
>> On Sep 25, 2017, at 6:33 PM, somu subscribe <somu.subscribe at gmail.com>
>> wrote:
>>
>> Hi Kenny,
>>
>> You could use a lazy var and initialise it with a closure.
>>
>> class PDAudioPlayer {
>>
>>     //Would be created lazily when first invoked
>>     lazy var mQueue : AudioQueueRef = {
>>
>>         //create an audioQueue and return that instance
>>         return audioQueue
>>     }()
>> }
>>
>> Thanks and regards,
>> Muthu
>>
>>
>> On 26 Sep 2017, at 9:12 AM, Kenny Leung via swift-users <
>> swift-users at swift.org> wrote:
>>
>> Hi All.
>>
>> I’m trying to implement the AudioQueue example from Apple in Swift, and
>> keep it as Swifty as I can. I’ve run into a problem where I have a let ivar
>> for the AudioQueue, but the only way to initialize that let ivar is to pass
>> a block to the function that creates the AudioQueue. I get the error,
>> "Variable 'self.mQueue' used before being initialized”. Is there any way to
>> get around this catch?
>>
>> Thanks!
>>
>> -Kenny
>>
>> The code follows.
>>
>> ———8<————8<————
>> class PDAudioPlayer {
>>     static let kNumberBuffers :Int = 3                              // 1
>>     //var mDataFormat:AudioStreamBasicDescription                     //
>> 2
>>     let mQueue :AudioQueueRef                                      // 3
>>     //var mBuffers :[AudioQueueBufferRef]                            // 4
>>     //var mAudioFile :AudioFileID?                                    //
>> 5
>>     var bufferByteSize :UInt32?                                     // 6
>>     var mCurrentPacket :Int64?                                      // 7
>>     var mNumPacketsToRead :UInt32?                                  // 8
>>     var mPacketDescs :UnsafePointer<AudioStreamPacketDescription>?  // 9
>>     var mIsRunning: Bool = false                                    // 10
>>
>>     let dispatchQueue :DispatchQueue
>>     let source :PDFileAudioSource
>>     var audioBuffers :[PDAudioBuffer]
>>
>>     init?(source:PDFileAudioSource) {
>>         self.source = source
>>         self.dispatchQueue = DispatchQueue(label:"AudioPlayer", qos:.
>> default, attributes:[], autoreleaseFrequency:.workItem, target:nil)
>>         self.audioBuffers = [PDAudioBuffer]()
>>
>>         var tempAudioQueue :AudioQueueRef?
>>         var dataFormat = source.mDataFormat
>>         let status = AudioQueueNewOutputWithDispatchQueue(&tempAudioQueue,
>> &dataFormat, 0, self.dispatchQueue) { [weak self] (queue, buffer) in
>> // ERROR on this line
>>             guard let this = self else {
>>                 return // block
>>             }
>>             guard let audioBuffer = this.audioBufferForAudioQueueBuffer(aqBuffer:buffer)
>> else {
>>                 return // block
>>             }
>>             this.source.fillBuffer(audioBuffer)
>>         }
>>         if status != 0 {
>>             return nil
>>         }
>>         guard let audioQueue = tempAudioQueue else {
>>             return nil
>>         }
>>         self.mQueue = audioQueue
>>     }
>>
>>     private func audioBufferForAudioQueueBuffer(aqBuffer:
>> AudioQueueBufferRef) -> PDAudioBuffer? {
>>         for buffer in self.audioBuffers {
>>             if buffer.audioQueueBuffer == aqBuffer {
>>                 return buffer
>>             }
>>         }
>>         return nil
>>     }
>> }
>>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
>>
>>
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
>>
> --
> -- Howard.
>
>
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
-- 
-- Howard.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170926/5e6ec6eb/attachment.html>


More information about the swift-users mailing list