9
typedef struct {
    NSString *activty;
    NSString *place;
    float latitude;
    float longitude;
} event;

typedef struct {
    event *thing;
    Node *next;
} Node;

This is the code I have in my .h file to create two structs to hold data (one for an events name/place/location, and one for the nodes of a linked list. I can use the event struct in the node struct, but I need to use the node struct within itself. In C++ this would work, but how can I achieve this in objective-c? Thank you!

Inanepenguin
  • 178
  • 1
  • 2
  • 9

3 Answers3

21

Why bother with a struct? Just use a class:

@interface MyEvent:NSObject
@property(copy) NSString *activity;
@property float latitude;
... etc ...
// and that linked list gunk
@property(retain) MyEvent *nextEvent;
@end

@implementation MyEvent
@synthesize activity, latitude, nextEvent;

- (void) dealloc
{
    [activity release], activity = nil;
    [nextEvent release], nextEvent = nil;
    [super dealloc];
}
@end

There is no significant overhead vs. a structure (if the method calls are really measurable, you could even expose ivars directly). Better yet, the moment you want to archive the struct, add business logic, or do anything else interesting, you can simply add methods.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • @tc, neither is the OP's original `event` struct, bbum is pointing out that a class would be a better alternative to a vanilla C struct as per his aforementioned reasons. – dreamlax Nov 24 '10 at 01:14
  • 1
    There; now it is a linked list. :) – bbum Nov 24 '10 at 03:49
  • Also, in ARC you cannot easily use objects in structs, so you'd have to use a class anyway. – Oliver Mason Mar 11 '14 at 16:47
  • Structs are way cleaner. The only reason to use a class is if it's Apple's class that comes with functions pre-made. I can't seem to find one, strangely. – sudo Mar 16 '14 at 21:12
  • 1
    @9000 Structs are way cleaner until you want to persist them.... into any Apple provided API... you want to add business logic... you want to provide various formatting logic... you want to take full advantage of ARC... etc.etc.etc... – bbum Mar 17 '14 at 01:59
2

You need to name your structure like you would in C. For example:

typedef struct Node {
    event *thing;
    struct Node *next;
} Node;

A better question, though, is why do you want to make this linked list in the first place? Why not use one of the container types provided by the framework?

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • What would you suggest to use instead to keep multiple data types connected? Should I just store my event structs in an NSMutableArray? – Inanepenguin Nov 23 '10 at 23:54
  • That'd be the normal thing. If you want a composite approach (eg, so you can pass plain structs down to existing C code) then you can use NSValue +valueWithPointer: to create an object capable of going into an Objective-C collection but which does nothing more than point to something else. – Tommy Nov 23 '10 at 23:59
  • One final question: I can't use addObject to push the struct to the array... What would be the proper way to do this? Thank you! – Inanepenguin Nov 24 '10 at 00:49
  • 1
    -1 undefined behaviour; _Node is a reserved identifier (anything starting with _[A-Z_] is in C). – tc. Nov 24 '10 at 00:51
  • @tc, good catch - in this case it's unlikely to be a problem, but easily fixed. – Carl Norum Nov 24 '10 at 03:09
-1

I think you'll find that it doesn't work in C++ (but they might have changed the grammar rules so that it does). You probably mean something more like this:

struct Node {
    event *thing;
    Node *next;
};

That works in C++ because Node is equivalent to struct Node if there isn't already something called Node (this sometimes causes puzzling errors when Foo is both a class and the instance method of another class, which happens in some coding styles).

The fix is to say struct Node. I prefer this; it seems more pure. There are some good reasons to use a typedef (e.g. things like TUInt64 which might have historically been a struct due to lack of compiler support). If you do use a typedef, there's no reason to give the struct a different name since they're in different namespaces (IIRC structs are a "tag namespace").

The usual typedef version is something like this:

typedef struct Node Node;
struct Node {
    event *thing;
    Node *next;
};

Alternatively, change the file extension to .mm and then it works because you're compiling Objective-C++!

tc.
  • 33,468
  • 5
  • 78
  • 96