iOS:UIView子类init或initWithFrame:?

我做了一个具有固定框架的UIView的子类。 所以,我可以重写init而不是initWithFrame: 例如:

- (id)init {
    if ((self = [super initWithFrame:[[UIScreen mainScreen] bounds]])) {
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

-initWithFrame:的Xcode文档说:“如果以编程方式创建视图对象,则此方法是UIView类的指定初始值设定项。子类可以重写此方法以执行任何自定义初始化,但必须在实现开始时调用super 。 “

“指定初始值设定项”是什么意思?


指定的初始化器是所有其他初始化器必须调用的初始化器。 UIView和子类有点不寻常,因为它们实际上有两个这样的初始化程序: -initWithFrame:-initWithCoder:取决于如何创建视图。 你应该重写-initWithFrame:如果你正在代码中实例化视图, -initWithCoder:如果你从一个笔尖加载它。 或者,您可以将代码放在第三个方法中,并覆盖这两个初始化方法,以便他们调用第三个方法。 事实上,这通常是推荐的策略。

因此,例如,您可以创建一个UIView子类ClueCharacter ,该子类具有自己的初始化方法: -initWithPerson:place:thing: ClueCharacter 然后,您可以像这样创建您的视图:

OBJ-C:

ClueCharacter *mustard = [[ClueCharacter alloc] initWithPerson:@"Col. Mustard"
                                                         place:kInTheStudy
                                                         thing:kTheRope];

迅速:

var mustard = ClueCharacter("Col. Mustard", place: kInTheStudy, thing: kTheRope)

这很好,但为了初始化对象的UIView部分,您的方法必须调用指定的初始值设定项:

OBJ-C:

-(id)initWithPerson:(NSString*)name place:(CluePlace)place thing:(ClueWeapon)thing
{
    if ((self = [super initWithFrame:CGRectMake(0, 0, 150, 200)])) {
        // your init stuff here
    }
}

迅速:

func init(name: String, place : CluePlace, thing : ClueWeapon)
{
    if (self = super.init(CGRectMake(0, 0, 150, 200))) {
       // your init stuff here
    }
}

如果你想调用你的子类的initializer -init ,只要你在实现中调用了-initWithFrame:


UIView调用[super init]完全等于[super initWithFrame:CGRectZero]


在具有多个初始程序的Objective-C类中,指定的初始化程序是执行有意义工作的程序。 所以,通常你有一个有几个初始者的班级,他说:

- (id)initWithRect:(CGRect)someRect;

- (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour;

- (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour
             linkTo:(id)someOtherObject;

在这种情况下,你通常(但不是总是)说第三个是指定的初始化程序,并执行另外两个例如

- (id)initWithRect:(CGRect)someRect
{
    return [self initWithRect:someRect setDefaultColour:NO];
}

- (id)initWithRect:(CGRect)someRect setDefaultColour:(BOOL)setDefaultColour
{
    return [self initWithRect:someRect setDefaultColour:setDefaultColour
                   linkTo:nil];
}

如果一个班级只有一个初始者,那么这就是指定的初始者。

在你的情况下,按照最佳做法,你应该实现initWithFrame:并且也是一个vanilla init:调用initWithFrame:用你的正常尺寸。 正常的约定是你可以在子类中的init中添加新的变体,但不应该带走任何东西,并且你总是在指定的初始化程序中进行实际的初始化工作。 这允许父类中的任何初始化方法都不会提供新的实现,仍然可以与您的子类适当地协作。

链接地址: http://www.djcxy.com/p/87719.html

上一篇: iOS: UIView subclass init or initWithFrame:?

下一篇: Subclassed UIView from NIB File not typed to subclass