Singleton在Objective-C中共享数据源

时间:2008-12-10 08:49:44

标签: iphone objective-c singleton

嘿伙计们 - 我正在编写一个非常简单的iPhone应用程序。数据来自plist文件(基本上是NSDictionary),我正在尝试加载到单例类中,并使用我的各种视图控制器来访问数据。

这是我的单身人士的实施(在this thread之后重新建模)

@implementation SearchData

@synthesize searchDict;
@synthesize searchArray;

- (id)init {
    if (self = [super init]) {
        NSString *path = [[NSBundle mainBundle] bundlePath];
        NSString *finalPath = [path stringByAppendingPathComponent:@"searches.plist"];
        searchDict = [NSDictionary dictionaryWithContentsOfFile:finalPath];
        searchArray = [searchDict allKeys];
    }

    return self;
}

- (void)dealloc {
    [searchDict release];
    [searchArray release];
    [super dealloc];
}

static SearchData *sharedSingleton = NULL;

+ (SearchData *)sharedSearchData {
    @synchronized(self) {
        if (sharedSingleton == NULL)
            sharedSingleton = [[self alloc] init];
    }   
    return(sharedSingleton);
}

@end

每当我尝试访问我的应用程序中的其他地方的searchDict或searchArray属性时(如TableView委托),就像这样:

[[[SearchData sharedSearchData] searchArray] objectAtIndex:indexPath.row]

我得到一个异常说明*** - [NSCFSet objectAtIndex:]:无法识别的选择器发送到实例0x5551f0

我不确定为什么objectAtIndex消息被发送到NSCFSet对象,我觉得我的单例实现错误或者什么。我还尝试了一个更复杂的单例实现,就像苹果在aforementioned thread中推荐的那样,并且遇到了同样的问题。感谢您提供的任何见解。

3 个答案:

答案 0 :(得分:11)

-init方法中,您直接访问实例变量,而不是保留它们。它们正在被取消分配,并且它们的内存在应用程序的生命周期中被其他对象用完。

保留您在那里创建的对象,或使用非便利方法生成它们。

searchDict = [[NSDictionary alloc] initWithContentsOfFile:finalPath];
searchArray = [[searchDict allKeys] retain];

答案 1 :(得分:1)

每当你分配合成变量时,都要通过'self'来完成,所以:

- (id)init {
  if (self = [super init]) {
      NSString *path = [[NSBundle mainBundle] bundlePath];
      NSString *finalPath = [path stringByAppendingPathComponent:@"searches.plist"];
      self.searchDict = [NSDictionary dictionaryWithContentsOfFile:finalPath];
      self.searchArray = [searchDict allKeys];
  }

  return self;

}

还要确保将这些变量设置为在头文件中“保留”。

答案 2 :(得分:0)

  

嗨,当我们通过'self'分配合成变量时,你能告诉我有什么好处吗?谢谢shiva

通过setter设置值;它会释放先前的值并保留您指定的值。