【iOS】singleton的属性,以及getter在使用上的一点问题

昨天看了iTunes上standford 公开课视频《Developing iOS 7 Apps for iPhone and iPad》,给自己打了打基础。

看完了一会就觉得自己以前的写法很“垃圾”,所以现在动手改了改风格,先改的是property的getter和setter。

视频里说在getter里做初始化比init里要好很多,结合我的实践,在我的单例中,我一直对没地方初始化property而耿耿于怀。


比如在单例中:

@implementation DDKStageArray

NSManagedObjectContext *context=nil;


+(DDKEquipArray *)arrayInstance{

    static dispatch_once_t pred = 0;

    dispatch_once(&pred, ^{

        singleton = [[self alloc]init]; // 跳到allocWithZone:

    });

    DDKAppDelegate *delegate = [UIApplication sharedApplication].delegate;

    context = delegate.managedObjectContext;

    return singleton;

}

. . .

@end

如果定义成一个@property (weak, nonatomic)NSManagedObjectContext *context;

然后尝试在arrayInstance中给他init,会发现根本不允许在那里放置property。退而求其次,我可以把property放在-(void)init方法里面,arrayInstance自己会调用-(void)init。后来为了解决创建多实例的问题,又搞了个+ (id)allocWithZone:(struct _NSZone *)zone方法,结果-(void)init方法不会被调用了。

// 防止[[DDKStageArray alloc]init]产生多实例

+ (id)allocWithZone:(struct _NSZone *)zone{

    @synchronized(self){

        count++;

        singleton = [super allocWithZone:zone];

        return singleton;

    }

    return nil;

}

这种多线程单例是我抄的,为啥要搞个计数器现在还不明白。总之property没法好好初始化。我就搞了个类静态量 NSManagedObjectContext  *context= nil ; 这下类方法就可以对他初始化了。可是这玩意因为是单例,所以如果有多个单例的话,类静态量是不允许重名的,否则符号冲突


列了一大堆现象,问题两个(上文标红),现在理一理头绪,我到底想干啥?给单例加上property,就这么简单。


然后我觉得getter很不错!

@interface BBUEquipArray ()

@property (weak, nonatomic)NSManagedObjectContext *equipContext;

@property (weak, nonatomic)NSEntityDescription *entityDescription;

@end


@implementation DDKEquipArray


+(DDKEquipArray *)arrayInstance{

    static dispatch_once_t pred = 0;

    dispatch_once(&pred, ^{

        singleton = [[self alloc]init]; // 跳到allocWithZone:

    });

    return singleton;

}

不要的全砍掉,代码清爽很多

写上getter,只写一个,另一个就不贴了。

#pragma mark - Getter

- (NSManagedObjectContext *)equipContext

{

    if (!_equipContext) {

        DDKAppDelegate *delegate = [UIApplication sharedApplication].delegate;

        _equipContext = delegate.managedObjectContext;

    }

    return _equipContext;

}

编译通过,好像不错的样子?理论上调用equipContext的时候,我getter都会给你初始化。

跑一跑,直接throw exception。。。exception不贴了,太丢人。问题代码在这里:

DDKCoreDataEquip *event = [NSEntityDescription insertNewObjectForEntityForName:@"DDKCoreDataEquip" inManagedObjectContext:_equipContext];


他说 _equipContext 为nil?为啥呢,作为参数传给方法的对象,并不会调用getter

BBUCoreDataEquip *event = [NSEntityDescription insertNewObjectForEntityForName:@"BBUCoreDataEquip" inManagedObjectContext:self.equipContext];

该省的不能省了,这里必须让他调用一次getter把他初始化咯,改成 self . equipContext 目标达成!


【结论】

在使用getter做初始化的时候,特别小心那些被当做参数传递的属性。务必使用self.property来保证getter的调用。


你可能感兴趣的:(ios,Singleton,property,getter)