Dissappearing string

  • I can not for the life of me figure this one out.

    Here is my code...
        PRINT_APPEND(@"\n%d", [theAttributedString retainCount]);
        DESCRIBE(theAttributedString);
        TRACE;
        [theSudokuTextField setAttributedStringValue: theAttributedString];
        theAttributedString = [theSudokuTextField attributedStringValue];
        PRINT_APPEND(@"\n%d", [theAttributedString retainCount]);
        DESCRIBE(theAttributedString);
        TRACE;

    and this is the console output for an execution that works...

    1
    theAttributedString (NSConcreteAttributedString) ...
    2 3 4 6 8 { NSFont = "\"BaskOldFace 9.00 pt. P [] (0x1589f0) fobj=0x46a5e0, spc=2.25\"";}
    -[Controller updatePossibilitiesDisplay:] @ 1133

    3
    theAttributedString (NSConcreteAttributedString) ...
    2 3 4 6 8 { NSFont = "\"BaskOldFace 9.00 pt. P [] (0x1589f0) fobj=0x46a5e0, spc=2.25\"";}
    -[Controller updatePossibilitiesDisplay:] @ 1138

    and this is the console output for an execution that works...

    1
    theAttributedString (NSConcreteAttributedString) ...
    1 2 3 4 5 6 7 8 9{ NSFont = "\"BaskOldFace 9.00 pt. P [] (0x119ce0) fobj=0x3e25bc0, spc=2.25\"";}
    -[Controller updatePossibilitiesDisplay:] @ 1133

    1
    theAttributedString (NSConcreteAttributedString) ...

    -[Controller updatePossibilitiesDisplay:] @ 1138

    Note that the retainCount has changed in the first case but not in the second.
    Does anyone have any ideas as to what is happening?

    Charlie Dickman
    <3tothe4th...>
  • On 15/05/2012, at 11:38 AM, Charlie Dickman wrote:

    > Note that the retainCount has changed in the first case but not in the second.
    > Does anyone have any ideas as to what is happening?

    No, but relying on, peeking at or otherwise taking any notice of retain counts is a sure path to madness.

    All you need to do is follow the ownership rules and forget about what the actual retain count is, especially for a complex object like NSAttributedString.

    WHat is the actual problem you're trying to solve?

    --Graham
  • On 15.05.2012, at 03:38, Charlie Dickman wrote:
    > Note that the retainCount has changed in the first case but not in the second.
    > Does anyone have any ideas as to what is happening?

    This is object-oriented programming. *anything* can have happened. While the external API is guaranteed and defined, encapsulation means you can't rely on any internal behaviours. When you call setAttributedString:, all you know is that you can release your copy of the string afterwards if you don't need it anymore. There is no guarantee what the text field will do with it. It could

    - copy the string (which means the retain count stays 1, and the string gets deallocated when you release it)
    - retain the string once
    - retain the string several times
    - schedule a thread that layouts the text asynchronously in the background and performs an additional retain on the string while it runs (which means depending on system load, locks and string length, it could still be retained by the running thread, or not, on the next line after the setAttributedString: call)

    There is really no way for you to tell what is happening, particularly by looking at the retain count. There may be optimizations, there may be autorelease pools, there may be other helper objects that hold on to your string while they do work with it.

    Why are you looking at the retain count? It is a bit like looking at the footprints in front of a factory trying to gage how many people work there. In the morning they might be accurate, in the afternoon right after lunch break start they may be double, and if someone urgently had to go to the pharmacy you might be off by two. There are better ways to spend your time.

    Cheers,
    -- Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
  • On 16.05.2012, at 15:02, Uli Kusterer wrote:
    > - copy the string (which means the retain count stays 1, and the string gets deallocated when you release it)

    Forgot to mention: When you *really* have an NSAttributedString (an immutable object), -copy can even be optimized out and be the same as a retain. OTOH if the string given is an NSMutableAttributedString, -copy actually creates an NSAttributedString from that (you'd have to call -mutableCopy to get an NSMutableAttributedString out instead). So there are a lot of factors, including who created the string and how, that influence the retain count going through the very same code.

    Cheers,
    -- Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
  • The actual problem is that I am telling an NSTextfield to set it's contents (the method is actually a part of NSCell from which NSTextfield inherits it) and it does not appear in the textfield. It used to work but I have no idea what I did to break it.

    On May 16, 2012, at 12:59 AM, Graham Cox wrote:

    >
    > On 15/05/2012, at 11:38 AM, Charlie Dickman wrote:
    >
    >> Note that the retainCount has changed in the first case but not in the second.
    >> Does anyone have any ideas as to what is happening?
    >
    >
    > No, but relying on, peeking at or otherwise taking any notice of retain counts is a sure path to madness.
    >
    > All you need to do is follow the ownership rules and forget about what the actual retain count is, especially for a complex object like NSAttributedString.
    >
    >
    > WHat is the actual problem you're trying to solve?
    >
    > --Graham
    >
    >

    Charlie Dickman
    <3tothe4th...>
  • On May 16, 2012, at 9:44 AM, Charlie Dickman wrote:

    > The actual problem is that I am telling an NSTextfield to set it's contents (the method is actually a part of NSCell from which NSTextfield inherits it)

    No; NSTextField inherits that method from NSControl.
    (It _contains_ an NSTextFieldCell, which inherits a method of the same name from NSCell. I know, controls vs. cells is confusing…)

    > and it does not appear in the textfield. It used to work but I have no idea what I did to break it.

    Only thing I can guess is that you passed in a mutable attributed string and later changed its contents. If the control didn’t internally create and store a copy of the original string, this will change the string it contains behind its back.

    —Jens
  • And a good "guess" it was because it got me to add the release and = nil to the code...

    possible[strlen(possible)] = '\0';
    NSString *possibleString = [NSString stringWithFormat: @"%s", possible];
    NSAttributedString *theAttributedString =
                 [[NSAttributedString alloc ] initWithString: possibleString
          attributes: theAttributes];
    [theSudokuTextField setAttributedStringValue: theAttributedString];
    [theAttributedString release];
    theAttributedString = nil;

    and now it's working again. However, as you can see, theAttributedString itself is not mutable.

    Thanks millions!

    On May 16, 2012, at 1:13 PM, Jens Alfke wrote:

    >
    > On May 16, 2012, at 9:44 AM, Charlie Dickman wrote:
    >
    >> The actual problem is that I am telling an NSTextfield to set it's contents (the method is actually a part of NSCell from which NSTextfield inherits it)
    >
    > No; NSTextField inherits that method from NSControl.
    > (It _contains_ an NSTextFieldCell, which inherits a method of the same name from NSCell. I know, controls vs. cells is confusing…)
    >
    >> and it does not appear in the textfield. It used to work but I have no idea what I did to break it.
    >
    > Only thing I can guess is that you passed in a mutable attributed string and later changed its contents. If the control didn’t internally create and store a copy of the original string, this will change the string it contains behind its back.
    >
    > —Jens

    Charlie Dickman
    <3tothe4th...>
  • On Wed, May 16, 2012 at 12:39 PM, Charlie Dickman <3tothe4th...> wrote:
    >        possible[strlen(possible)] = '\0';

    This can't possibly work. strlen() depends on the string already being
    \0 terminated. You can't use strlen() to find the position to add a
    \0.
  • On Wed, May 16, 2012 at 12:39 PM, Charlie Dickman <3tothe4th...> wrote:
    >        NSString *possibleString = [NSString stringWithFormat: @"%s", possible];

    ... and this line is something you shouldn't do. There are a ton of
    correct methods to create an NSString from a C string:

    +stringWithCString:encoding:
    +stringWithUTF8String:
    -initWithBytes:length:encoding:
    -initWithBytesNoCopy:length:encoding:freeWhenDone:
    -initWithCString:encoding:
    -initWithData:encoding:
    -initWithUTF8String:
  • An excellent observation! That was probably causing all kinds of problems yet to be seen!

    Thanks so much!

    On May 16, 2012, at 1:51 PM, Stephen J. Butler wrote:

    > On Wed, May 16, 2012 at 12:39 PM, Charlie Dickman <3tothe4th...> wrote:
    >> possible[strlen(possible)] = '\0';
    >
    > This can't possibly work. strlen() depends on the string already being
    > \0 terminated. You can't use strlen() to find the position to add a
    > \0.

    Charlie Dickman
    <3tothe4th...>
  • On 17/05/2012, at 2:44 AM, Charlie Dickman wrote:

    > The actual problem is that I am telling an NSTextfield to set it's contents (the method is actually a part of NSCell from which NSTextfield inherits it) and it does not appear in the textfield. It used to work but I have no idea what I did to break it.

    Does the text field have a formatter? That might be changing its behaviour in all sorts of ways. For example, if a number formatter has a maximum value, your second string numerically has a much higher value than the first, so it might be being rejected by the formatter.

    But the mutable vs. immutable suggestion seems more likely.

    --Graham
  • YOU NAILED IT! My formatter is returning an absurd value when presented with the string! Now if I can just figure out the regular expression to describe the string I'll be in business.

    A trillion thanks!

    On May 16, 2012, at 6:56 PM, Graham Cox wrote:

    >
    > On 17/05/2012, at 2:44 AM, Charlie Dickman wrote:
    >
    >> The actual problem is that I am telling an NSTextfield to set it's contents (the method is actually a part of NSCell from which NSTextfield inherits it) and it does not appear in the textfield. It used to work but I have no idea what I did to break it.
    >
    >
    > Does the text field have a formatter? That might be changing its behaviour in all sorts of ways. For example, if a number formatter has a maximum value, your second string numerically has a much higher value than the first, so it might be being rejected by the formatter.
    >
    > But the mutable vs. immutable suggestion seems more likely.
    >
    > --Graham
    >

    Charlie Dickman
    <3tothe4th...>
previous month may 2012 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