NSTextField to display NSMutableString

Discussion in 'Mac Programming' started by larswik, Jul 4, 2011.

  1. macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    Hello, This code works when I test it.
    Code:
    NSString *tempString;
    NSMutableString *valueAppender;
    
    - (IBAction)ONE:(id)sender {
        tempString = @"1";
        [mathField setStringValue: tempString];
    I then tried to swap out to an NSMutableString 'valueAppender' for this next code I get a warning "Incompatible pointer types assigning to 'NSMutableString *' from 'NSString *'"


    Code:
    - (IBAction)ONE:(id)sender {
        valueAppender = @"1";
        [mathField setStringValue: valueAppender];
    }
    I understand the error message and I am looking through the Apple documentation in the methods to find a method for a NSMutableString. I thought about trying to assign the NSMutableString to a NSString and have the text field then display the string?

    Thanks,

    -Lars
     
  2. macrumors 6502a

    Joined:
    Jan 23, 2010
    Location:
    San Diego, CA USA
    #2
    MutableString is a subclass of String though. You might be trying to set the wrong item.
     
  3. jiminaus, Jul 4, 2011
    Last edited: Jul 4, 2011

    macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #3
    Read the error message carefully.
     
  4. thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #4
    Incompatible pointer types would lead me to believe that the pointer to the NSMutableString object. Is different then a standard pointer to a NSString object. I tried code like this but I also get an error at runtime.

    Code:
    - (IBAction)ONE:(id)sender {
        [valueAppender setString: @"1"];
        [mathField setStringValue: valueAppender]; 
    mathField is just an NSTextField. SetSrtingValue is a valid method in that is listed for NSTextField class. But valueAppender is a NSMutableString and not just an NSString. That is the only thing that I see that can cause the problem. Is my thinking wrong?

    Here is the error message that pops up with the degugger

    "*** Assertion failure in -[NSTextFieldCell _objectValue:forString:errorDescription:], /SourceCache/AppKit/AppKit-1038.35/AppKit.subproj/NSCell.m:1531
    2011-07-04 20:15:32.028 Xp Calc2[1715:903] Invalid parameter not satisfying: aString != nil"
     
  5. jiminaus, Jul 4, 2011
    Last edited: Jul 4, 2011

    macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #5
    You're reading the error message around the wrong way. The error is about assigning from NSString* to NSMutableString*, not the other way around.

    You've got an NSString* that you're trying to assign to an NSMutableString*. This cannot be done safely, so the compiler is flagging in the error.

    The problem was with this line:
    Code:
      valueAppender = @"1";
    
    As you know @"1" results in an NSString*. But valueAppender is an NSMutableString* variable. Now do you see the error?


    Your last post is more on track. It's okay, assuming you've alloc'ed and init'ed valueAppender. If you haven't, you're sending setString: to nil, which isn't going to do anything. And on second reading of your reply, you indeed haven't because NSTextField is complaining about it being null.

    The general way to alloc and init an NSMutableString from another string is to use either [[NSMutableString alloc] initWithString:@"abc"] or [@"abc" mutableCopy].

    However, you could just alloc and init an NSMutableString object in this classes' init, and then your code would work as posted.


    BTW It is perfectly fine to use an object of a subclass instead of a class, thanks to the Liskov substitution principle. But you cannot go the other way and substitute an object of a superclass for a class.
     
  6. thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #6
    Thanks Jim, I see what is happening now. I have not alloc and init the NSMutableString. I was watching the Lynda.com video on learning objective-C the video said to the effect that if I did not write the class then I should not release it. I think he used NARC as long as I have not used New, Alloc, Retain or Copy the system would handle the memory management.

    So for NSString *tempString; I did not alloc or init (instantiate) it. But for NSMutableString I should?

    I was getting a nil response and now I know why, thanks.

    Is there a way I can know if I am supposed to instantiate a system class, or if it handles it's self? I looked in the reference and could not see examples.

    Thanks again Jim, I would have been staring at that one the whole night.

    -Lars
     
  7. Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #7
    Just my $0.02, IMHO this is part of the unlearning of what you have learned in procedural code that makes me lean towards folks learning Objective-C first.

    You should always lean towards using alloc init (or equivalent) for objects, but your procedural instincts say assign with =.

    B
     
  8. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #8
    This is wrong. The rules of memory management apply regardless of whether you've written the class or not.

    This is right. I've never seen the NARC acronym, but it works. You are responsible for sending a release message to an object returned by any of these methods. Sending an autorelease message counts as sending a release message.

    You must not send a release message to an object returned by any other methods.

    Print out the Basic Memory Management Rules, read them, re-read them often, keep them close by, and refer to them often; until they become instinct.

    You don't have an object unless you obtain one by either alloc'ing and init'ing one, or by getting a pointer to one from another variable or the result of a method.

    When you're considering instance variables, sometimes you'll need to think about the greater lifetime of an object because an instance variable might be assigned in one method and then later used in another.

    NSString is slightly special in that there's special syntax them. @"abc" is pretty much equivalent to [NSString stringWithUTF8String:"abc"]. Notice it's not of the NARC methods, so you're not responsible for releasing the object obtained using the @"abc" syntax. But it does result in a pointer to an NSString object.


    (An aside: Technically the memory managent rules say you're required to retain the object obtained using the @"abc" syntax if you want to keep around an pointer to it, in for example an instance variable. But most people don't do that, and so far the runtime has supported that, and probably always will.)
     
  9. macrumors 6502a

    Joined:
    Dec 2, 2008
    #9
    Memory Management

    The Basic Memory Management rules are well-defined. It seems that that would be a topic amenable to computer solution at the compiler level. What would your reaction be to a compiler that automatically counted memory references and did the retain/release for you?

    This would be at the compiler level, not garbage collection done at run time.
     
  10. macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #10
    What a coincidence... http://clang.llvm.org/docs/AutomaticReferenceCounting.html
     
  11. thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #11
    There is SOOOO much to learn in Objc-C and remember. I am amazed people can pick up books and try to learn it at home in their spar time. If I don't do little fun experiments as I learn to help me retain what I learn I would forget.

    balamw- I am happy I went with C and then back to Object-C. I don't have to worry about learning an If statement while learning what objects are as so on. The last day of my Pascal class the instructor said he hoped people would take his Java class next semester. He said that even though Object oriented programming is a different way of thinking, Object's are still filled with procedural code.

    Jim - I will read Memory reference. My brain is on overload reading and watching videos and then having what I thought I just learned corrected on this forum :) You wrote this line of code
    This will create an object with a pointer? Is it some default pointer that gets created. I thought you had to define the variable pointer like NSString *ptr ?


    If I ever figure this out Objective - C I am going to make a program to teach Objective - C Programming. Have it be a hands on with graphical representations of '-(void)', 'NSString' and so on located in different bins. Then a question saying " Create an object that places the string "Hello World" in memory". I would then open my class bin and drag out the graphical representation of an NSString class. Then in my variable bin pull out a pointer and rename it. Then from the memory bin I pull out an Alloc. Then from a method bin I would pull out a graphical representation of a Method that works with that class like initWithString. Then type in Hello World and press the execute button to see if it works, or give a clue as to why it did not.

    Then as you keep learning you can download more moduals online to build up the library (bins) as you grow.

    Not the program Alice, but where you look at code and not dance astronauts.

    Someone should make an app for this :)

    -Lars
     
  12. Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #12
    There's an anecdote at the beginning of Cocoa in a Nutshell that bears repeating.

    Clearly everyone learns and retains things differently.

    I first learned BASIC, Pascal and some C back in the 8-bit days, so I can't know for sure how things would be if I hadn't learned procedural, linear code first.

    However, I can say that I've gone through the unlearning (a.k.a. retraining) process twice. First with Agilent VEE (a visual programming language that was my first introduction to multi-threaded programming, where code can exectute in highly non-linear paths, and then again with Objective-C. All my previous OOP-y work in C++ and Java was informal didn't really test my perception of objects as fundamentally different than fancy structures.

    In both cases VEE and Objective-C (and to some extent MATLAB) I often see folks getting in deep trouble because they insist on trying to make it fit their existing mindset instead of letting go and learning how to use it for what it is.

    Since learning some Objective-C I've also gone back to some C++ with STL and find that my code is much more "objectified" now.

    B
     
  13. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #13
    A variable is just a box to put values into. A pointer to an object exists, remember a pointer is just a memory address, regardless of it being stored in a variable.

    Take the example of integers and consider the following snippet of code.
    Code:
    int x = 10;
    int y = 5;
    int a = 2 * (x + y);
    When the expression on the last line is being executed, after x is added to y, the resulting 15 exists. It's not stored in any variable, but it exists (likely in a CPU register). Only after 15 is multiplied by 2, is the resulting 30 stored in the variable a.

    Similarly with @"abc". The result of executing @"abc" is a pointer to an NSString object containing the text "abc". What you do with that pointer is up to you. You can store in a variable, you can pass it as an argument to a function or a message, you can even sent it a message like so.
    Code:
    [@"abc"
       writeToFile:[@"~/Desktop/abc" stringByExpandingTildeInPath]
        atomically:NO
          encoding:NSUTF8StringEncoding
             error:NULL];  // It's actually bad to pass NULL here, don't copy this
     
  14. macrumors 68000

    Sydde

    Joined:
    Aug 17, 2009
    #14
    When the compiler sees something like

    x = "abc";​

    it sees a constant value that it cannot easily embed into a code stream, so it puts it into a specific area reserved for constants, globals and statics and generates code that accesses that location (on some platforms, like PPC, this is even true for a value like 2.5 which cannot be embedded into the code stream). When you change the constant to @"abc", exactly the same thing happens, except some additional stuff is added so that the constant value will serve as an instance of a NSString. Because the reserved location is not in the dynamic heap area, retain and release messages will have no effect.

    And yes, "abc" constitutes 4 bytes (with \0) so it could in fact easily be embedded into to code stream, but I think most compilers will not attempt an optimization at that level, and rightly so.
     
  15. thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #15
    balamw - Lots of learned and unlearned languages. I think I am safe to start to unlearning Pascal :)


    Jim - So funny you should mention this.
    In my Pascal I got into it with my teacher and he thought I was nuts or did not get it. I had a local variable integer in a function like int a;. When the function returned control back to Main it the said something like total = a; I argued that when the function ended it destroyed that local int a variable so the the code snippet total = a; would not work. because 'a' no longer existed. He did not get what I was saying. Your 'Computer Register' answered that question.

    I understand that all variables have an address and storage space. In C '&' accessed the address and '*' accessed the contents of that address. I used this a lot with functions to swap out values in memory locations.


    Sydde - Thanks for the detailed explanation.

    -Lars
     
  16. Moderator

    balamw

    Staff Member

    Joined:
    Aug 16, 2005
    Location:
    New England
    #16
    :)

    The danger for me is actually the closer languages.

    Perhaps it's just me, but when I first learned C all my C code looked like Pascal, and similarly for C++ all my C++ looked like C. :p

    Learning to let go and use higher level Objective-C/Cocoa instead of rolling your own and relying on your fundamental C concepts is the hard part.

    At least it was for me, YMMV.

    B
     
  17. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #17
    If you can get your hands on one of the many Computer Architecture and Organization type books, it will fill in much of the picture for you.
     
  18. thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #18
    balamw - The reason I got into programming last year was because I wanted to build a motion control rig for my camera. I shoot a lot of TV commercials and lots of restaurants. I wanted a small motion control rig that I could fly a camera over the food to get different looking shots. My friend Mike is an electronics engineer and designs custom circuit boards for printers to drive stepper motors and so on. He said if I learn programming he would build me the hardware. C seemed to be the main language people used to program for this type of stuff. I would think you could use Objective - C to build a GUI interface that would work to pull this off?

    Anyways, that is years off still and many smaller projects to do on the way.

    Jim - Those books might still be beyond my understanding but I will look into it.

    -Lars
     
  19. macrumors 6502a

    Joined:
    Dec 2, 2008
    #19
    That sounds pretty cool. Keep plugging away at the programming!
     

Share This Page