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

来源:互联网 发布:巨人网络财务报表 编辑:程序博客网 时间:2024/05/15 15:34

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

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

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


比如在单例中:

@implementation DDKStageArray

NSManagedObjectContext *context=nil;


+(DDKEquipArray *)arrayInstance{

    staticdispatch_once_t pred = 0;

   dispatch_once(&pred, ^{

        singleton = [[selfalloc]init];// 跳到allocWithZone:

    });

   DDKAppDelegate *delegate = [UIApplicationsharedApplication].delegate;

    context = delegate.managedObjectContext;

    returnsingleton;

}

. . .

@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 = [superallocWithZone:zone];

       return singleton;

    }

    return nil;

}

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


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


然后我觉得getter很不错!

@interfaceBBUEquipArray ()

@property (weak, nonatomic)NSManagedObjectContext *equipContext;

@property (weak,nonatomic)NSEntityDescription *entityDescription;

@end


@implementation DDKEquipArray


+(DDKEquipArray *)arrayInstance{

    staticdispatch_once_t pred = 0;

   dispatch_once(&pred, ^{

        singleton = [[selfalloc]init];// 跳到allocWithZone:

    });

    returnsingleton;

}

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

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

#pragma mark - Getter

- (NSManagedObjectContext *)equipContext

{

    if (!_equipContext) {

       DDKAppDelegate *delegate = [UIApplicationsharedApplication].delegate;

        _equipContext = delegate.managedObjectContext;

    }

    return_equipContext;

}

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

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

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


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

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

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


【结论】

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


0 0
原创粉丝点击