无法更新单例属性

时间:2012-10-22 19:03:01

标签: objective-c xcode singleton

我遇到了一个愚蠢的问题,我已经尝试了几乎所有东西(买了3本书,经历了整个谷歌:))但没有任何帮助。在我看来,解决方案应该非常简单......

我需要在Objective-C中声明一个单例(对于iOS应用程序,如果这很重要),它应该有一些我需要从其他类更新的属性。但我不能这样做 - 属性不会更新,它们在“init”方法中设置的值相同。

我创建了一个简单的应用来测试这个问题。这就是我所做的:

首先,我已经声明了一个示例类及其子类,我将其用作单例的属性:

@interface Entity : NSObject

@property (nonatomic, strong, readwrite) NSMutableString * name;

@end

@implementation Entity
@synthesize name;

@end

@interface Company : Entity

@property (nonatomic, strong, readwrite) NSMutableString * boss;
@property (nonatomic) int rating;

@end

@implementation Company
@synthesize boss, rating;

@end

然后我根据“Big Nerd Ranch的iOS编程指南”一书中描述的方法声明单例本身。为了清楚起见,我使用自定义类和标准NSMutableString作为属性:

@class Company;

@interface CompanyStore : NSObject
{
     NSMutableString * someName;
}

@property (nonatomic, strong, readwrite) Company * someCompany;
@property (nonatomic, strong, readwrite) NSMutableString * someName;

+ (CompanyStore *) store;
- (void) modifyCompanyProperties;

@end

@implementation CompanyStore
@synthesize someCompany, someName;

// Declaring the shared instance
+ (CompanyStore *) store
{
    static CompanyStore * storeVar = nil;

    if (!storeVar) storeVar = [[super allocWithZone:nil] init];

    return storeVar;

}

// Replacing the standard allocWithZone method
+ (id) allocWithZone:(NSZone *)zone
{
    return [self store];
}

然后我用初始值初始化所有属性:

- (id) init
{
    self = [super init];
    if (self) {
        someCompany = [[Company alloc] init];
        [someCompany setBoss:[NSMutableString stringWithFormat:@"John Smith"]];
        [someCompany setName:[NSMutableString stringWithFormat:@"Megasoft"]];
        [someCompany setRating:50];

        someName = [[NSMutableString alloc] initWithString:@"Bobby"];
    }
    return self;
}

从另一个类(在视图中显示内容的视图控制器):

1。我得到了单身人士属性的值。一切都没问题 - 我得到了“约翰史密斯”,“Megasoft”,“Bobby”和我的int值50。来自 init 方法的值。

2。我从该视图控制器更改单例的属性(使用多种方式 - 我现在不确定哪一个是正确的):

- (IBAction)modify2Button:(id)sender {

    CompanyStore * cst = [CompanyStore store];

    NSMutableString * name = [[NSMutableString alloc] initWithString:@"Microcompany"];
    NSMutableString * boss = [[NSMutableString alloc] initWithString:@"Larry"];

    [[[CompanyStore store] someCompany] setName:name];
    cst.someCompany.boss = boss;

    NSMutableString * strng = [[NSMutableString alloc] initWithString:@"Johnny"];
    [cst setSomeName:strng];
}

...然后我想再次获得价值。我仍然得到旧的设置 - “约翰史密斯”,“Megasoft”等等,即使当我在其中一个字符串上设置断点时,我可以看到单身人士的名字属性是“微公司”而不是“Megasoft”。休息时间......但它似乎没有被分配。

3。然后我正在尝试另一件事 - 我正在从视图控制器调用一个单例的私有方法,它为属性分配另一组值。这是单身人士的方法:

- (void) modifyCompanyProperties
{
    NSMutableString * boss = [[NSMutableString alloc] initWithString:@"George"];
    NSMutableString * name = [[NSMutableString alloc] initWithString:@"Georgeland"];

    [someCompany setBoss:boss];
    [someCompany setName:name];
    [someCompany setRating:100000];

    [someName setString:@"Nicholas"];

}

4。我正试图再次从视图控制器获取更新的属性值...仍然得到那些“John Smith”,“Megasoft”......没有任何变化。

似乎单例的属性只设置了一次然后我无法更改它们,即使它们的属性被声明为“readwrite”。

看起来我不明白一些简单的事情。 如果有人可以解释如何正确地宣布和更新单身人士的属性,我将非常感激。

1 个答案:

答案 0 :(得分:1)

我注意到的第一件事是你在store方法的主体中声明“storeVar”。这看起来对我来说非常错误,因为每次你打电话给你都会重新初始化单身人士。你应该像这样声明变量:

static CompanyStore * storeVar = nil;
    @implementation CompanyStore
    @synthesize someCompany, someName;

    // Declaring the shared instance
    + (CompanyStore *) store
    {

        if (!storeVar) storeVar = [[super allocWithZone:nil] init];

        return storeVar;

    }

你的init方法也不完全正确,因为你不想在单例初始化之后再次调用init,所以你必须检查它,如果它已经初始化你应该只返回它:

- (id) init
{
if (storeVar!=nil) {
return storeVar;
}

    self = [super init];
    if (self) {
        someCompany = [[Company alloc] init];
        [someCompany setBoss:[NSMutableString stringWithFormat:@"John Smith"]];
        [someCompany setName:[NSMutableString stringWithFormat:@"Megasoft"]];
        [someCompany setRating:50];

        someName = [[NSMutableString alloc] initWithString:@"Bobby"];
    }
    return self;
}

另外,这不是一个错误,只是一个建议 - 你可以抛弃@synthesize,因为ios 6因为编译器会自动生成它。但同样,使用它并不是一个错误。希望它有所帮助