关于自定义UIView的xib初始化和加载的问题

Abo*_*oud 1 iphone

我正在尝试创建一个自定义UIView类,它从包含该视图接口的xim文件加载.我试图在我的自定义视图的init方法中封装[NSBundle mainBundle] loadNibNamed ...],如下所示:

- (id)init 
{    
    self = [super init];
    if (self) 
    {
        NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"LoadingV" owner:self options:nil];
        self = [(LoadingV*)[nibViews objectAtIndex: 0] retain];
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

我想知道:

  1. 这是一种可以接受的方式吗?有没有更好的方法?
  2. 鉴于我没有在dealloc中调用[self release],我应该保留"保留"吗?

干杯AF

Evg*_*kov 7

不,这是不可接受的,这是不好的做法,你实际上有内存泄漏.

更好的方法是使用一种称为"工厂"的模式.

例:

@interface CustomView: UIView
@end

@implementation CustomView
- (void)awakeFromNib {
    // custom view loaded from nib
}
@end

@interface UIView (Nib)
+ (UIView *)viewFromNib:(NSString *)nibName bundle:(NSBundle *)bundle;
@end

@implementation UIView (Nib)
+ (UIView *)viewFromNib:(NSString *)nibName bundle:(NSBundle *)bundle {
    if (!nibName || [nibName length] == 0) {
        return nil;
    }

    UIView *view = nil;

    if (!bundle) {
        bundle = [NSBundle mainBundle];
    }

    // I assume, that there is only one root view in interface file
    NSArray *loadedObjects = [bundle loadNibNamed:nibName owner:nil options:nil];
    view = [loadedObjects lastObject];

    return view;
}
@end
Run Code Online (Sandbox Code Playgroud)

用法:

// CustomView.xib contains one View object with its class set to "CustomView"
CustomView *myView = (CustomView *)[UIView viewFromNib:@"CustomView" bundle:nil];
Run Code Online (Sandbox Code Playgroud)