1

In the @interface, I have this declaration:

@interface myClass {
   NSDictionary * myData;
}

@property (nonatomic, assign) NSDictionary * data;
+ (id) initWithData:(NSDictionary *)data;

@end

In the @implementation, I have this code:

@implementation

@synthesize data;

+ (id) initWithData:(NSDictionary *)freshData {
    self = [super init];
    if (self) {
        self->data = freshData;
    }
    return self;
}

@end

But I got error Incomplete definition of type 'struct objc_class on self->data.

If I change it into self.data, I got error Member reference type 'struct objc_class *' is a pointer; did you mean to use '->'?

If I remove the self, I got error `Instance variable 'data' accessed in class method.'

But if I change the method type from + (class method) to - (instance method), I cannot access the init.

And I cannot fix this error by change the assignment from data to myData either.

How should I make a constructor?

The link that I have learned from (but not helping) are:

3 Answers 3

4

You can do it like this also

+ (id) initWithData:(NSDictionary *)freshData {
    return [[self alloc]initWithData:freshData];
}
- (instancetype) initWithData:(NSDictionary *)freshData {

    NSParameterAssert(freshData != nil);

    self = [super init];

    if (self) {
        self.data = freshData;
    }

    return self;
}
Sign up to request clarification or add additional context in comments.

3 Comments

If I only implement - (instancetype) initWithData:(NSDictionary *)freshData without + (id) initWithData:(NSDictionary *)freshData, what's the downside?
Well you can do that also, if there is not any issue with creating the object ofthat class, as with instance method you need to create the object of that class to use that method and with class method you can call that method with Class.
Check this also for class method vs instance method - stackoverflow.com/questions/1053592/…
2

In general, I would not expect an init* method to be a class method. Generally you have a class method with a name like default*, shared*, or *withDictionary:. So for a class named myClass, I'd expect to see this:

+ (myClass*)myClassWithDictionary:(NSDictionary*)dict
{
    return [[myClass alloc] initWithDictionary:dict];
}

This can be important when the static analyzer analyses your code, for example. Naming is significant in Objective-C and hints the compiler (and analyzer) as to what the code's intent is.

3 Comments

You mean like [UIColor colorWithCGColor:] ?
Yes, that's what I meant.
Okay, I think I know what's wrong that I can't access instance init method constructor... I forgot to do alloc first before init. That's why I only can access the init method if I changed the init into class constructor, because I immediately wrote [MyClass initWithData:]. I'm so used to Swift simplicity that when I have to go back to Objective C, I kinda forget about the drill... Then your answer reminds me why the init must be instance method, not class method. Thanks!
1

Do not using public init method (+)

+ (id) initWithData:(NSDictionary *)data;

Change to

- (instancetype) initWithData:(NSDictionary *)data;

And I highly recommend you to use instancetype instead of id (reference )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.