help with closing file handle

  • Hello,

    I have the following code :

    - (int)useArchive: (NSString*)path {

        if (nil == path)
            return -1;
        NSFileHandle *fileHandle = [NSFileHandle
    fileHandleForReadingAtPath: path];
        if (nil == fileHandle)
            return -1;
        [fileHandle closeFile];
    ...

    When I run it, while stepping through the closing of the file handle,
    the gdb window shows the
    error :

    2008-02-08 11:56:09.166 TesterBundleDebugger[408] *** -[NSCFArray
    appendString:]: selector not recognized [self = 0x30a9a0]
    2008-02-08 11:56:09.167 TesterBundleDebugger[408] *** Uncaught
    exception: <NSInvalidArgumentException> *** -[NSCFArray
    appendString:]: selector not recognized [self = 0x30a9a0]

    I don't understand what is happening.
    Help me.
  • On Feb 8, 2008 8:06 AM, Daniel Luis dos Santos <daniel.dlds...> wrote:
    > When I run it, while stepping through the closing of the file handle,
    > the gdb window shows the
    > error :
    >
    > 2008-02-08 11:56:09.166 TesterBundleDebugger[408] *** -[NSCFArray
    > appendString:]: selector not recognized [self = 0x30a9a0]
    > 2008-02-08 11:56:09.167 TesterBundleDebugger[408] *** Uncaught
    > exception: <NSInvalidArgumentException> *** -[NSCFArray
    > appendString:]: selector not recognized [self = 0x30a9a0]
    >
    > I don't understand what is happening.

    We're going to think through this like programmers, so that maybe you
    can nail bugs like this yourself in the future.

    Read carefully: something's trying to send -appendString: to an
    NSArray (NSCFArray is the name of the real, concrete toll-free-bridged
    subclass of NSArray that we all use unknowingly).  -[NSFileHandle
    closeFile] is the method causing the problem, and we can safely assume
    that the implementation of NSFileHandle is correct.  The only thing
    you're provided to it is the NSString you received as the first
    argument to -useArchive:.  -appendString: is indeed defined on
    NSMutableString.

    Seems like we've found a likely cause of the issue: the NSString
    you're getting and giving to NSFileHandle is really an NSCFArray;
    whoever called -useArchive: screwed up.  There should have been a
    warning generated about "distinct Objective-C types".  If you haven't
    already, turn on "treat warnings as errors" in your project settings.

    --Kyle Sluder
  • From what I understood, In your opinion it seems that I supplied a
    NSArray to the NSFileHandle instead of a NSString.
    But I didn't. I passed the argument to the [NSFileHandle:
    fileHandleForReadingAtPath] as a string literal (@"...").
    I still don't get it.

    On Feb 8, 2008, at 4:15 PM, Kyle Sluder wrote:

    > On Feb 8, 2008 8:06 AM, Daniel Luis dos Santos
    > <daniel.dlds...> wrote:
    >> When I run it, while stepping through the closing of the file handle,
    >> the gdb window shows the
    >> error :
    >>
    >> 2008-02-08 11:56:09.166 TesterBundleDebugger[408] *** -[NSCFArray
    >> appendString:]: selector not recognized [self = 0x30a9a0]
    >> 2008-02-08 11:56:09.167 TesterBundleDebugger[408] *** Uncaught
    >> exception: <NSInvalidArgumentException> *** -[NSCFArray
    >> appendString:]: selector not recognized [self = 0x30a9a0]
    >>
    >> I don't understand what is happening.
    >
    > We're going to think through this like programmers, so that maybe you
    > can nail bugs like this yourself in the future.
    >
    > Read carefully: something's trying to send -appendString: to an
    > NSArray (NSCFArray is the name of the real, concrete toll-free-bridged
    > subclass of NSArray that we all use unknowingly).  -[NSFileHandle
    > closeFile] is the method causing the problem, and we can safely assume
    > that the implementation of NSFileHandle is correct.  The only thing
    > you're provided to it is the NSString you received as the first
    > argument to -useArchive:.  -appendString: is indeed defined on
    > NSMutableString.
    >
    > Seems like we've found a likely cause of the issue: the NSString
    > you're getting and giving to NSFileHandle is really an NSCFArray;
    > whoever called -useArchive: screwed up.  There should have been a
    > warning generated about "distinct Objective-C types".  If you haven't
    > already, turn on "treat warnings as errors" in your project settings.
    >
    > --Kyle Sluder
  • Hello, again.

    I have found the solution to the problem. It seems that I have to
    pass a mutable string with the path to the file handle's factory
    method. Looking back at the output of the error, now it seems pretty
    obvious. My worry now is that I am new to the macos development
    environment, and I am programming while looking at the documentation
    I have installed in my machine. I have tiger, but upgraded to xcode
    2.5 from the version supplied with OSX. The documentation for the
    NSFileHandle class shows me in its signature an NSString as its
    argument.
    Is this common in apple API's or am I looking at the wrong document's ?

    On Feb 8, 2008, at 4:15 PM, Kyle Sluder wrote:

    > On Feb 8, 2008 8:06 AM, Daniel Luis dos Santos
    > <daniel.dlds...> wrote:
    >> When I run it, while stepping through the closing of the file handle,
    >> the gdb window shows the
    >> error :
    >>
    >> 2008-02-08 11:56:09.166 TesterBundleDebugger[408] *** -[NSCFArray
    >> appendString:]: selector not recognized [self = 0x30a9a0]
    >> 2008-02-08 11:56:09.167 TesterBundleDebugger[408] *** Uncaught
    >> exception: <NSInvalidArgumentException> *** -[NSCFArray
    >> appendString:]: selector not recognized [self = 0x30a9a0]
    >>
    >> I don't understand what is happening.
    >
    > We're going to think through this like programmers, so that maybe you
    > can nail bugs like this yourself in the future.
    >
    > Read carefully: something's trying to send -appendString: to an
    > NSArray (NSCFArray is the name of the real, concrete toll-free-bridged
    > subclass of NSArray that we all use unknowingly).  -[NSFileHandle
    > closeFile] is the method causing the problem, and we can safely assume
    > that the implementation of NSFileHandle is correct.  The only thing
    > you're provided to it is the NSString you received as the first
    > argument to -useArchive:.  -appendString: is indeed defined on
    > NSMutableString.
    >
    > Seems like we've found a likely cause of the issue: the NSString
    > you're getting and giving to NSFileHandle is really an NSCFArray;
    > whoever called -useArchive: screwed up.  There should have been a
    > warning generated about "distinct Objective-C types".  If you haven't
    > already, turn on "treat warnings as errors" in your project settings.
    >
    > --Kyle Sluder
  • On Feb 9, 2008, at 14:14, Daniel Luis dos Santos wrote:

    > I have found the solution to the problem. It seems that I have to
    > pass a mutable string with the path to the file handle's factory
    > method. Looking back at the output of the error, now it seems
    > pretty obvious. My worry now is that I am new to the macos
    > development environment, and I am programming while looking at the
    > documentation I have installed in my machine. I have tiger, but
    > upgraded to xcode 2.5 from the version supplied with OSX. The
    > documentation for the NSFileHandle class shows me in its signature
    > an NSString as its argument.
    > Is this common in apple API's or am I looking at the wrong
    > document's ?

    You must show your code to get help.

    I guess that you pass an autoreleased string to the file handle, and
    the exceptions you get are raised when the file handle try to send a
    message to the object you passed, which does not exists any more. The
    same address is used now by another object, (an NSArray) which
    complain about unrecognized selectors. This is a very common error
    for Cocoa beginners.

    You should read carefully the memory management guidelines: http://
    developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Tasks/
    MemoryManagementRules.html

    Best Regards,

    Nir Soffer
  • On 09.02.2008, at 13:14, Daniel Luis dos Santos wrote:
    > I have found the solution to the problem. It seems that I have to
    > pass a mutable string with the path to the file handle's factory
    > method. Looking back at the output of the error, now it seems pretty
    > obvious.

      That should not be necessary. If it says NSString*, it should be
    allowed to be any NSString*, there's no reason why it would need to be
    a particular subclass of NSString*. I guess you'll have to post your
    code if you want us to be able to help you more. You must be doing
    something else wrong, maybe releasing an object too early (this can
    happen indirectly by passing an autoreleased object somewhere where it
    will be accessed after it has been released), or otherwise screwing up
    memory.

      If you're not clear about memory management, you may want to read
    the docs on memory management in Cocoa someone else already posted, or
    my article on memory management in general:

    <http://www.zathras.de/howmemorymanagementworks.htm>

    which is not Cocoa-specific, but starts from the very bottom. There's
    also a follow-up (part of my C tutorial) that expands on that and
    illustrates a few of the things that can go wrong when managing memory
    the wrong way by giving an example:

    <http://www.zathras.de/angelweb/masters-of-the-void-book6.htm>

    If you already knew all that, maybe it'll help someone lurking here.

    Cheers,
    -- M. Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
    http://www.zathras.de
  • On Feb 9, 2008 5:22 AM, Nir Soffer <nirs...> wrote:

    > I guess that you pass an autoreleased string to the file handle, and
    > the exceptions you get are raised when the file handle try to send a
    > message to the object you passed, which does not exists any more

    It would be the responsibility of NSFileHandle to retain or copy the
    string. Likely it is an over-released string because of a bug in
    memory management.

    However as you said we need to see more code to help.

    -Shawn
  • That was all the code. The only thing that is not showing is the
    string literal that gets passed through the argument list.

    Thanks anyway

    On Feb 9, 2008, at 3:23 PM, Shawn Erickson wrote:

    > On Feb 9, 2008 5:22 AM, Nir Soffer <nirs...> wrote:
    >
    >> I guess that you pass an autoreleased string to the file handle, and
    >> the exceptions you get are raised when the file handle try to send a
    >> message to the object you passed, which does not exists any more
    >
    > It would be the responsibility of NSFileHandle to retain or copy the
    > string. Likely it is an over-released string because of a bug in
    > memory management.
    >
    > However as you said we need to see more code to help.
    >
    > -Shawn