Cannot assign to self out of a method in the init family?

If your method is an initializer, it must start with init:

- (instancetype)initWithDropDown:(UIButton *)b:(CGFloat *)height:(NSArray *)arr:(NSString *)direction

Otherwise, you can change it to be a class method, and return a new instance:

+ (instancetype)showDropDown:(UIButton *)b:(CGFloat *)height:(NSArray *)arr:(NSString *)direction
{
    btnSender = b;
    animationDirection = direction;
    YourClassName obj = [[self alloc] init];
    if (obj) {
        // Initialization code
        // …
    }
    return obj;
}

Check your spelling in this method

-(id)initwithArray:(NSArray *)array  

Code: (Objective-C)

-(id)initWithArray:(NSArray *)array  

You can't initialize self outside an init method because of the following convention:

If an object’s class does not implement an initializer, the Objective-C runtime invokes the initializer of the nearest ancestor instead.

and because the name of some methods is recognized by the memory management system of the runtime:

When the name of a method starts with alloc init, retain, or copy, it means it's being created for the caller, who has the responsibility to release the object when he is done with it. Otherwise the method returned is not owned by the caller, and he has to indicate he wants to keep it calling retain on the object.

Therefore, all initializers should be written as a variation of this:

- (id) init {
    self = [super init];
    if (self){
        _someVariable = @"someValue";
    }
    return self;
}
  • Don't use if ((self = [super init])) because it's ugly.
  • Don't use self.someVariable because the object may not be initialized yet. Use direct variable access instead (_someVariable).
  • We write self = [super init] and not just [super init] because a different instance may be returned.
  • We write if (self) because there will be cases where it will return nil.

However, there are two more problems with your method:

  • You are combining object creation ([super init]) and an action (-showDropDown::::) in the same method. You should write two separate methods instead.
  • The name of your method is -showDropDown::::. Objective-C programmers expect self documenting method names like -showDropDown:height:array:direction: instead. I guess you come from a different language, but when in Rome, do as Romans do, or else you won't be playing along with the rest of the team.

I think you have to rename your initializer (currently named showDropDown) to something that starts with init (like initWithDropDown…). This used to be just a convention (albeit a reasonable one), but now with ARC it’s a hard requirement.