Re: How to implement an array of dicts

  • Objective:
    Write a preset manager plugin for Quartz Composer, using the settings
    pane as the UI.

    I have created a plugin with a series of "settings".
    The first is called presetNum.
    Whenever this value changes, all of the other settings in the pane
    get updated with values from an array (of presets).

    Question:
    I created some data - dictionaries and arrays - in the "init" method.
    I had to retain this data in order to get things to work.
    The pointers to these datum are all instance variables.
    From my reading of the docs, I should not have to retain, because
    the instance variables are referring to them, and the ivars continue
    to exist.
    So - why did I have to retain these?

    Q2:
    Is there a better way to do this?
    Is there some example code out there that does something like this?
    It seems that I am really just building a database editor where
    "presetNum" is the record index.

    Code attached:
  • On Dec 20, 2007, at 4:36 PM, Jack Hayward wrote:

    > I had to retain this data in order to get things to work.
    > The pointers to these datum are all instance variables.
    > From my reading of the docs, I should not have to retain, because
    > the instance variables are referring to them, and the ivars continue
    > to exist.
    >
    No.
    *In a managed memory environment*, simply because an object is an
    instance variable does not mean it won't go away if you haven't got
    the memory management semantics right.

    The rules are spelled out here:
    <http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Tasks/
    MemoryManagementRules.html
    >

    Since you created defaultPreset, defaultPreset2, and presets without
    using any methods that conform to the "ownership rule", you don't own
    them until you retain them.
    Read the rules above to understand why this is fundamentally flawed:

    > newParm = [[[NSDictionary alloc] initWithObjectsAndKeys:
    > self.parmName1, @"name",
    > self.value1, @"val",
    > self.duration1, @"dur",
    > nil] retain];
    >

    You should also consider the advice given in <http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articl
    es/mmPractical.html#//apple_ref/doc/uid/TP40004447-DontLinkElementID_4
    > -- use accessor methods to help you get memory management right.
    And in general, do a sanity check against the documentation and sample
    code.  The documentation generally gets the memory management right;
    you shouldn't anywhere in the documentation see an example like the
    code above for newParam.

    Lastly, it's not clear why you have a finalize method -- it is not
    used unless you're using garbage collection.

    mmalc
  • On Dec 20, 2007, at  Dec 20, 2007  |  5:08 PM, mmalc crawford wrote:

    >
    > On Dec 20, 2007, at 4:36 PM, Jack Hayward wrote:
    >
    >> I had to retain this data in order to get things to work.
    >> The pointers to these datum are all instance variables.
    >> From my reading of the docs, I should not have to retain, because
    >> the instance variables are referring to them, and the ivars
    >> continue to exist.
    >>
    > No.
    > *In a managed memory environment*, simply because an object is an
    > instance variable does not mean it won't go away if you haven't got
    > the memory management semantics right.
    >
    > The rules are spelled out here:
    > <http://developer.apple.com/documentation/Cocoa/Conceptual/
    > MemoryMgmt/Tasks/MemoryManagementRules.html>
    >
    > Since you created defaultPreset, defaultPreset2, and presets
    > without using any methods that conform to the "ownership rule", you
    > don't own them until you retain them.
    > Read the rules above to understand why this is fundamentally flawed:
    >
    >> newParm = [[[NSDictionary alloc] initWithObjectsAndKeys:
    >> self.parmName1, @"name",
    >> self.value1, @"val",
    >> self.duration1, @"dur",
    >> nil] retain];
    >>
    >
    > You should also consider the advice given in <http://
    > developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/
    > Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447-
    > DontLinkElementID_4> -- use accessor methods to help you get memory
    > management right.
    > And in general, do a sanity check against the documentation and
    > sample code.  The documentation generally gets the memory
    > management right; you shouldn't anywhere in the documentation see
    > an example like the code above for newParam.
    >

    Thanks for all of the above - I will read up.

    > Lastly, it's not clear why you have a finalize method -- it is not
    > used unless you're using garbage collection.
    >

    The finalize method is supplied as part of the QC-plugin template.
    I thought that was where I was supposed to release anything that I
    created/retained.
  • On Dec 20, 2007, at 5:13 PM, Jack Hayward wrote:

    > The finalize method is supplied as part of the QC-plugin template.
    > I thought that was where I was supposed to release anything that I
    > created/retained.
    >
    It's only used in a garbage collected environment, and you're strongly
    encouraged not to have any need to implement it.  In a managed memory
    environment, you need to implement dealloc.  See <http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals
    /CocoaObjects/chapter_3_section_6.html#//apple_ref/doc/uid/TP40002974-CH4-S
    W40
    >.

    mmalc
  • On Dec 20, 2007, at 5:13 PM, Jack Hayward wrote:

    > The finalize method is supplied as part of the QC-plugin template.
    >
    Oh, it's set up as a mixed-mode project.  *If* you need to support
    both garbage collection and managed memory, then for the most part --
    as far as Cocoa is concerned -- you simply write your code as if you
    were just supporting managed memory (the retains, releases, etc. are
    no-ops).  You should implement a dealloc method just as you would
    normally, and as suggested previously you should try to avoid writing
    a finalize method.  The one minor difference is that if you use an
    autorelease pool, when you're finished with it you send it 'drain'
    instead of 'release'.
    If you're allocating your own memory, or using Core Foundation
    objects, things are a little trickier -- for more on the latter see <http://developer.apple.com/documentation/Cocoa/Conceptual/GarbageCollection
    /Articles/gcCoreFoundation.html
    >.

    mmalc
previous month december 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Go to today