代码之家  ›  专栏  ›  技术社区  ›  7stud

mutableArrayValueForKey:未调用countOf<Key>,countOfSongs

  •  0
  • 7stud  · 技术社区  · 9 年前

    我的确切问题是:

    http://www.cocoabuilder.com/archive/cocoa/236041-kvc-array-proxy-objects.html#236058

    I'm trying to understand how the proxy object which is returned from
    mutableArrayValueForKey: works and I've hit a bit of a wall.  I get
    what the proxy is and why it exists.  I have a test app which allows
    me to do things to/with the collection it represents and it all works
    fine.  The problem is that when I try to implement some of the methods
    mentioned in the developer docs under the "Key-Value Coding Accessor
    Methods" section.  There are some methods there which if implemented
    in the hosting object (i.e. the original recipient of the
    mutableArrayValueForKey: call) are to be called by the proxy when the
    proxy is asked to do various things.  The hitch is that in my test app
    I can't get the -countOf<key> or -objectIn<key>AtIndex methods to be
    invoked.
    In reading through the docs, it seems that a number of methods need
    to be implemented before any of these (dare I call them 'proxy
    methods'?) are called.  I implemented a whole slew of them - including
    a number that shouldn't need to be - and ended up with this set: (The
    test app is based on a Playlist->Songs->Song model where "songs" is
    the NSMutableArray which lives in the Playlist class in which I'm
    interested in getting a count of its member songs.)
    
    - (unsigned int)countOfSongs;
    - (Song *)objectInSongsAtIndex:(unsigned int)index;
    - (NSArray *)songsAtIndexes:(NSIndexSet *)indexes;
    - (void)getSongs:(Song **)buffer range:(NSRange)inRange;
    - (void)insertObject:(Song *)newSong inSongsAtIndex:(unsigned int)idx;
    - (void)removeObjectFromSongsAtIndex:(unsigned int)idx;
    
         Even simple test code like this fails:
    
    Playlist *myPlaylist = [[[Playlist alloc] init] autorelease];
    id arrayProxy = [myPlaylist mutableArrayValueForKey:@"songs"];
    [arrayProxy insertObject:[[[Song alloc] initWithName:@"test" andLength:
    10] autorelease] atIndex:0];
    unsigned int theCount = [arrayProxy count];
    
    I've got all the properties defined, all the methods written, etc.
    Yet when I call [arrayProxy count] my countOfSongs method in the
    Playlist class isn't touched.  The right answer is returned, but it's
    apparently coming from the runtime going to the array directly and
    getting the answer via NSArray's count method.
    Oddly enough, when I do the insertObject call in line #3 the
    insertObject:inSongsAtIndex: method IS called... so some of this stuff
    works as I believe it is supposed to.  Unfortunately it's the other
    stuff that's driving me nuts.  I've been working on this one for a
    couple of days now and have tried everything I could come up with -
    including some really silly, paranoid stuff - and have made no progress.
    Can anybody help me with a suggestion as to what I might be doing
    wrong or what I'm missing?
    Thanks!
    

    而那里的答案——虽然看起来对手术有所帮助——对我来说并没有任何帮助。

    这是我的游乐场代码:

    import Cocoa
    
    "hello"
    
    class Song {
        dynamic var title = "Hello"
    }
    
    "hello"
    
    
    class PlayList: NSObject {
    
        /*dynamic*/ var songs = NSMutableArray()
        //private var theSongs = NSMutableArray()
    
        //var countOfSongs: Int = 100
    
        func countOfSongs() -> Int {
            println("count of songs")
    
            return 100
            //return theSongs.count + 100
        }
    
        func objectInSongsAtIndex(i: Int) -> AnyObject? {
            println("getter")
            return songs[i]
            //return theSongs[i]
        }
    
    
        func insertObject(song:AnyObject, inSongsAtIndex index:Int) {
            println("insert")
            songs[index] = song as! Song
            //theSongs[index] = song as! Song
        }
    
        func removeObjectFromSongsAtIndex(index:Int) {
            println("remove")
            songs.removeObjectAtIndex(index)
            //theSongs.removeObjectAtIndex(index)
    
        }
    
    }
    
    
    
    "hello"
    
    var playlist = PlayList()
    
    "hello"
    
    let arrayProxy = playlist.mutableArrayValueForKey("songs")
    
    "hello"
    
    arrayProxy.addObject(Song())  //successfully calls proxy method => outputs "insert"
    arrayProxy.removeObjectAtIndex(0)  //successfully calls proxy method => outputs "remove"
    arrayProxy.count   //=> 0  ???
    

    我需要对代码进行哪些更改,以便在编写时调用countOfSongs属性或方法:

    arrayProxy.count
    
    2 回复  |  直到 9 年前
        1
  •  2
  •   Martin R    9 年前

    来自参考文章 http://www.cocoabuilder.com/archive/cocoa/236041-kvc-array-proxy-objects.html#236058 :

    有关访问者搜索顺序的文档显示 首选名为的方法 -<key> 超过相应的 -countOf<Key> - objectIn<Key>AtIndex: 方法。

    这意味着

    let arrayProxy = playlist.mutableArrayValueForKey("songs")
    let cnt = arrayProxy.count 
    

    访问的“songs”属性 Playlist 直接,如果有 财产。

    如果重命名属性,则它将按预期工作:

    class Song {
        dynamic var title = "Hello"
    }
    
    class PlayList: NSObject {
    
        var thesongs = NSMutableArray()
    
        func countOfSongs() -> Int {
            println("count of songs")
            return 100
        }
    
        func objectInSongsAtIndex(i: Int) -> AnyObject? {
            println("getter")
            return thesongs[i]
        }
    
        func insertObject(song:AnyObject, inSongsAtIndex index:Int) {
            println("insert")
            thesongs[index] = song as! Song
        }
    
        func removeObjectFromSongsAtIndex(index:Int) {
            println("remove")
            thesongs.removeObjectAtIndex(index)
        }
    }
    
    var playlist = PlayList()
    let arrayProxy = playlist.mutableArrayValueForKey("songs")
    let cnt = arrayProxy.count  
    println(cnt)
    

    输出:

    count of songs
    100
    
        2
  •  1
  •   7stud    9 年前

    对于未来的搜索者,这里是一个完整的示例,它在OSX>应用程序>命令行工具(我检查了Swift的语言):

    import Foundation
    
    class Song {
        var title = "Hello"
    }
    
    class PlayList: NSObject {
    
        private var array: [Song] = []
    
        func countOfSongs() -> Int {
            println("countOfSongs() called")
            return array.count
        }
    
        /*
        //This also works:
        var countOfSongs: Int {
            println("countOfSongs property was accessed")
            return array.count
        }
        */
    
    
        func objectInSongsAtIndex(index: Int) -> AnyObject? {
            println("getter called")
            return array[index]
        }
    
        func insertObject(song:AnyObject, inSongsAtIndex index:Int) {
            println("inserting at index \(index)")
            array.insert(song as! Song, atIndex: index)
        }
    
        func removeObjectFromSongsAtIndex(index:Int) {
            println("removing at index \(index)")
            array.removeAtIndex(index)
        }
    
    }
    
    
    var playlist = PlayList()
    let arrayProxy = playlist.mutableArrayValueForKey("songs")
    arrayProxy.addObject(Song())
    
    println(arrayProxy.count)
    
    arrayProxy.objectAtIndex(0)
    arrayProxy.removeObjectAtIndex(0)
    
    println(arrayProxy.count)
    
    
    var playlist = PlayList()
    let arrayProxy = playlist.mutableArrayValueForKey("songs")
    
    arrayProxy.addObject(Song())
    println(arrayProxy.count)
    arrayProxy.removeObjectAtIndex(0)
    
    println(arrayProxy.count)
    
    --output:--
    countOfSongs() called
    inserting at index 0
    countOfSongs() called
    1
    getter called
    removing at index 0
    countOfSongs() called
    0
    

    我再也没有游乐场了!