2012-10-22 36 views
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 

然後我宣佈本身基於單在「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」,「鮑比」和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」等,我可以看到單身人士的姓名屬性是「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"]; 

} 

我試圖得到再次視圖控制器更新的屬性值...,仍然可以得到那些「約翰·史密斯」,「Megasoft」。 .. 沒有什麼變化。

似乎單身人士的屬性只設置一次,然後我不能改變他們,即使他們的屬性被聲明爲「讀寫」。

它看起來像我不明白簡單的東西。 如果有人可以解釋如何正確地聲明和更新單身屬性,我將非常感激。

+0

你可以嘗試刪除自己的'+(id)allocWithZone:(NSZone *)區域'實現並檢查問題是否重現? – Nekto

+0

嗨,刪除它 - 沒有幫助,沒有什麼改變:( – Andrey

回答

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()方法是不完全完成,如果它已經初始化你應該簡單地返回它:

- (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中,因爲編譯器會自動生成它。但是,再次使用它並不是一個錯誤。希望它有幫助

+0

嗨Yacana!非常感謝,這幾乎解決了我的問題! 我照你的建議做了,現在我可以通過調用更新單身人士的屬性一個方法 我想問題是init方法每次調用(這有點奇怪,但無論如何) 不幸的是,從其他類的更新(描述在 - (IBAction)modify2Button:(id)sender)仍然在任何想法有什麼可能是錯誤的嗎? 再次感謝! – Andrey

+0

另外,關於你聲明storeVar在商店方法的身體的關注我已經看到這種模式在單獨的聲明在2本書 - 「可可設計模式」和「大型書呆子牧場的iOS編程」第一本書他們沒有說出他們爲什麼要這樣做。在BNR書中,如果我理解正確,他們說靜態變量被聲明一次,稍後聲明代碼被編譯器忽略。這可能是他們爲什麼不擔心在單例方法中聲明變量的原因。儘管我普遍同意你的關心。 – Andrey

+0

你好安德烈。我沒有訪問xcode atm。今天晚些時候我會在這裏做一些測試併發布結果 – yacana