我遇到了一个愚蠢的问题,我已经尝试了几乎所有东西(买了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”。
看起来我不明白一些简单的事情。 如果有人可以解释如何正确地宣布和更新单身人士的属性,我将非常感激。
答案 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因为编译器会自动生成它。但同样,使用它并不是一个错误。希望它有所帮助