When to use structs ? (objective-c)

Discussion in 'Mac Programming' started by teek, Feb 11, 2010.

  1. teek macrumors member

    teek

    Joined:
    Feb 12, 2008
    Location:
    Norway
    #1
    Hi,

    I'm new to Objective-C (or C for that matter) and I'm wondering in what cases to use structs.

    Say I have a couple of classes which both contain

    title
    description

    otherwise they are not related whatsoever so subclassing is not an option. Would this be a suitable case for using a struct?

    What are the general pros and cons for struct usage ?
     
  2. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #2
    In general, don't use structs. Valid cases to use them would be a) when interacting with a C api that uses them, or b) when memory usage or exact memory layout is a primary concern (measure, don't guess, for memory usage. Most classes don't have enough instances for the overhead of an isa pointer to matter at all).
     
  3. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #3
    Well in your case I would probably not use a struct for that.

    I'd use composition, and/or a protocol to implement that.

    Since you didn't say if title and description were methods, ivars, or both, the question/code example would be difficult.


    Normally you use struct's when you need to have a small/fast way of storing or sending a piece of data. Usually composed of built in C types.

    Examples of good use of struct would be NSRange, NSPoint, CGRect so on...

    The idea is that the members of the struct are related in some way, and are built on C data types.

    Memory overhead is usually less of an issue than the method/function overhead of Objective-C classes. IMHO
     
  4. HiRez macrumors 603

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #4
    What's wrong with having two classes both containing "title" and "description"? Why would you want/need to use a struct here? If you're using Cocoa + Objective-C you will probably very rarely use a struct when you can make a class instead. Maybe for some very small, quick things with primitive values where you don't want the overhead of a class and message-sending (which aren't really much). For example, maybe you have 100,000 particles that need only x, y float values. But in general you will use Cocoa's classes like NSString, NSNumber (you can still use int and float primitives in classes if you want), NSData, Cocoa's collection classes like NSArray, NSDictionary, etc., and your own classes containing those.
     
  5. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #5
    Neither one is usually an issue.
     
  6. teek thread starter macrumors member

    teek

    Joined:
    Feb 12, 2008
    Location:
    Norway
    #6
    Nothing wrong with it I'm just trying to figure out the best way to do this while trying to learn objective-c.

    I need several objects which all contain a title and a description (sort of like NSObject's description method). Then, since they are in not related in any way I was thinking about using a struct to "group" these properties together so I wouldn't have to define them in each class header but use a struct instead.
    That was my idea anyway.

    Basically I have a bunch of classes which all have a title and description (NSString). And I figured maybe I could use a struct to "group" those properties together so I wouldn't have to define them in each class header.
    Maybe it doesn't make sense but that's my idea anyway.
     
  7. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #7
    Maybe it's because I am coming from an iPhone programming background, but there certainly is a reason why Apple chose structs over objects for all of those.

    an example from my own code.

    Code:
    typedef struct {
         double bin;
         int num;
    } BinType;
    
    Basically the double member "bin" is like a title/description of the BinType and is used for sorting as well as displaying.
    the int member num is like a running total of how many numbers went into this bin. num is also used in sorting.

    Ironically, later in development I wanted to add an NSMutableArray to this struct, and thus converted the struct into an object. But my code was certainly faster before the change. :eek:

    Do you need ivars? Or could you just return a string and make the string when something asks for it?

    Cause maybe a protocol would make sense.
     
  8. teek thread starter macrumors member

    teek

    Joined:
    Feb 12, 2008
    Location:
    Norway
    #8
    Yes I need ivars. Can I "require" a set of ivars if I use a protocol, or does that just require you implement a set of method (like an interface in Java)
     
  9. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #9
    By using an object in the first place you wouldn't have had to change your code. Then once everything worked you could go in, Shark your app, and determine whether or not it was worth changing that (say, to a CFMutableArray with custom callbacks so you could store the structs).

    Without really knowing your code, I can't say for sure, but another possibility would be to use an NSCountedSet, which will manage the 'num' for you in an efficient way. Lastly, why a double for bin type? That seems like a strange choice for an object you clearly have a lot of.

    There are certainly cases where message send overhead or isa pointer overhead matter, they're just fairly uncommon.
     
  10. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #10
    Because bin could be (and commonly is) any real number. Its for bar graphing, the "bin" member would sorta be the starting point for the numbers that would go into the bin.

    I'm not positive, but I don't see why you couldn't put an object pointer into a struct. So I could have put an NSMutableArray *array; or CFArrayRef *array; into the original struct and not had to change my code.

    I used the struct to rapidly prototype it, and it worked for my purposes, I'm just saying I'm not "anti-Struct". :cool:
     
  11. HiRez macrumors 603

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
  12. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #12
    Really, this sounds to me like the exact situation where you would subclass. If you need to create different types of objects, you create the superclass that has "title" and "description" and the methods you need to handle those ivars, then subclass from there. Every subclass will inherit those ivars as well as those methods. How much easier do you want it?
     
  13. autorelease macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #13
    Structs are used mainly in plain C and C++. The reason structs aren't used much in Objective-C is that it's not easy to store them in collections. You have to wrap them in NSValue objects or only store them in an NSPointerArray, and those can be pretty hard to understand.
     
  14. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #14
    But oh so easy to put into an object as part of composition and then store them in an NSArray.
     
  15. HiRez macrumors 603

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #15
    But if you're going to bother to do that, why not just make a class in the first place? Why bother with Objective-C if you're just going to go half way with it anyway? Embrace it.
     
  16. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #16
    An object instance itself is basically a unique kind of struct. To its own methods, its struct members (ivars) are accessed with abbreviated syntax (just the member name, much of the time). But this kind of struct can effortlessly be expanded, through subclassing. If you have the full header for the superclass, all of its ivars are directly accessible to any methods defined in a subclass.

    I find one of the best times to use a struct is when you need to pass a whole bunch of diverse variables (like a context) and would rather have a single argument (preferably a pointer to the struct) than a dozen. But this is also a pretty uncommon situation.
     
  17. Mac Player macrumors regular

    Joined:
    Jan 19, 2006
    #17
    You meant adding the struct to the mutable array? In that case I would use stl containers.

    HiRez he is coming from iPhone development. iPhone developers don't have multi Ghz multi GB machines to play with.
     
  18. autorelease macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #18
    OH GOD WHY
     
  19. Mac Player macrumors regular

    Joined:
    Jan 19, 2006
    #19
    I tell you why. Efficient storage, ability to use STL algoritms, no need to define callbacks like most general C container solutions.
     
  20. autorelease macrumors regular

    Joined:
    Oct 13, 2008
    Location:
    Achewood, CA
    #20
    I was exaggerating, I just wanted to type that. :D

    The STL is fine for pure C++. (though the Objective-C Foundation classes are probably easier to learn and use) If you're really concerned with performance (e.g. you're writing an OpenGL game) you should write the game core in C++ and only use Objective-C for a thin GUI layer around the game code. C++ and Objective-C do not mix well, so both sides should be kept as isolated as possible.

    If you're sticking to Objective-C, and need an array of structs for performance reasons, you can use NSPointerArray.
     
  21. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #21
    No I meant add an array to the struct. Meaning I ended up wanting to keep around a list of numbers in the bin.
     

Share This Page