您好,匿名用户

objective-c 单例继承问题

0 投票

今天在修改数据库,发现每个类都有自己的单例实现函数,然后很多冗余的逻辑,于是就想父类写一个单例函数,然后子类继承就可以生成各自的单例了.
结果发现俺错了...

+ (id)sharedInstance{
    static BaseDAO *kInstance = nil;
    NSLog(@"kInstance=%@", kInstance);
    @synchronized(self){
        if(kInstance == nil){
            kInstance = [[self alloc] init];
        }else{
        }
    }
    return kInstance;
}

结果是所有的子类得到的都是同一个单例,然后就unrecognized selector sent to instance
我看了下java是有这种功能的,因为可以把属性设置为static, oc刚试了不行.
不知道有木有方法实现各子类不同单例.

用户头像 提问 2012年 12月1日 @ Dante 上等兵 (291 威望)
分享到:

1个回答

0 投票
 
最佳答案

先说你错在哪:
虽然方法中self是不同的类,但是kInstance只有一个。
你只用[BaseDAO sharedInstance];一直都不会出问题
一旦[XXX sharedInstance]; kInstance已存在,不会再重新生成,返回的就是BaseDAO的单例。你对着BaseDAO的对象发XXX的消息当然会unrec sel。
总之,kInstace存的一直都是第一次调用sharedInstance时,接收消息的类的单例

你耳朵里有没有偶尔回旋起这样一句话:

多用组合,少用继承

你如果觉得用组合有绕路的感觉,我来炫下技:

NSObject+OTSharedInstance.h:

@interface NSObject (OTSharedInstance)

+ (id)sharedInstance;

@end

NSObject+OTSharedInstance.m:

#import <objc/runtime.h>

@implementation NSObject (OTSharedInstance)

+ (id)sharedInstance
{
    Class selfClass = [self class];
    id instance = objc_getAssociatedObject(selfClass, @"kOTSharedInstance");
    if (!instance)
    {
        instance = [[selfClass alloc] init];
        objc_setAssociatedObject(selfClass, @"kOTSharedInstance", instance, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return instance;
}

@end

内存不够用的话可能需要释放单例,补个释放的方法:

+ (void)freeSharedInstance
{
    Class selfClass = [self class];
    objc_setAssociatedObject(selfClass, SHARED_INSTANCE_KEY, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

测试代码:

#import "NSObject+OTSharedInstance.h"
id a;
id b;
for (int i = 0; i<10; i++)
{
    a = [UIWindow sharedInstance];
    NSLog(@"instance a : %@",a);
    b = [UIView sharedInstance];
    NSLog(@"instance b : %@",b);
}

如果你觉得用了上述方法,所有类都能产生单例太脏,可以新建个Protocol,单在Protocol中声明sharedInstace。需要单例的类自己多重继承一下

好用的话把答案勾给我

用户头像 回复 2012年 12月1日 @ Saber 中士 (1,252 威望)
选中 2012年 12月1日 @Dante
提一个问题:

相关问题

0 投票
1 回复 106 阅读
用户头像 提问 2014年 11月26日 @ Kassadin 中士 (1,440 威望)
0 投票
1 回复 62 阅读
用户头像 提问 2014年 8月2日 @ Brand 中士 (1,130 威望)
0 投票
1 回复 197 阅读
用户头像 提问 2012年 12月1日 @ Janna 上士 (1,772 威望)
0 投票
1 回复 133 阅读
用户头像 提问 2016年 6月16日 @ Warwick 中士 (1,306 威望)
0 投票
1 回复 401 阅读
用户头像 提问 2014年 1月21日 @ 阿尔托莉雅 上士 (1,542 威望)

欢迎来到随意问技术百科, 这是一个面向专业开发者的IT问答网站,提供途径助开发者查找IT技术方案,解决程序bug和网站运维难题等。
温馨提示:本网站禁止用户发布与IT技术无关的、粗浅的、毫无意义的或者违法国家法规的等不合理内容,谢谢支持。

IT技术交流群 - 随意问
欢迎访问随意问技术百科,为了给您提供更好的服务,请及时反馈您的意见。
...