1

我遇到了一个愚蠢的问题,我几乎尝试了所有东西(买了 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

然后我根据“iOS Programming Guide by Big Nerd Ranch”一书中描述的方法声明了单例本身。为了清楚起见,我同时使用我的自定义类和标准 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.我得到了单例属性的值。一切都好——我的 int 值得到了“John Smith”、“Megasoft”、“Bobby”和 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];
}

...然后我试图再次获得这些值。我仍然得到旧的集合 - “John Smith”,“Megasoft”等,即使当我在其中一个字符串上设置断点时,我可以看到单例的 name 属性是“Microcompany”而不是“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”......没有任何变化。

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

看起来我不明白一些简单的事情。如果有人能解释如何正确声明和更新单例中的属性,我将不胜感激。

4

1 回答 1

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 开始,编译器会自动生成它。但同样,使用它并不是一个错误。希望能帮助到你

于 2012-10-23T07:03:48.447 回答