2011-09-01 55 views
1

我有這個靜態/ singelton類有一個成員變量。Objective C - 釋放變量

一切都運行得很好,但是,當我退出應用程序,以及回來時,該成員變量會導致應用崩潰。

我試圖重新初始化成員變量,但似乎並沒有這樣的伎倆。

我在下面包括我的代碼示例,有沒有人看過這個?

頭(.h)文件中:

@interface Metrics : NSObject { 
Metrics *metrics; 
Distance *distance; 
} 

實施(.M)文件:

@implementation Metrics 

static Metrics *metrics = nil; 

+ (Metrics *)sharedInstance { 
@synchronized(self) { 
    if (metrics == nil) { 
     metrics = [[Metrics alloc] init]; 
    } 
} 

return metrics; 
} 

- (id)init { 
    self = [super init]; 

    if (self) { 

    } 

    return self; 
} 

-(void) setupDistance 
{ 
    distance = [[Distance alloc] init]; 
    distance.test; // it dies here after I quit the app and come back 
} 

而且它被使用,AppDelegate.m

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    [[Metrics sharedInstance] setupDistance]; 
} 

謝謝
Tee

+0

崩潰說的是什麼(即在控制檯崩潰時看到什麼,以及調用堆棧是什麼樣的)? – SVD

+0

這是一個iOS應用嗎?另外,請發佈Distance的聲明和'getTest'的實現; – Perception

+0

@Perception:什麼getTest?他正在調用方法測試作爲屬性。 –

回答

1

當你說「退出應用程序」時,你幾乎肯定意味着「將應用程序發送到後臺。」這不會終止您的應用程序。當你再次活躍時,你正在泄漏distance並分配一個新的。我懷疑test中的東西實際上是問題所在。

首先,請勿直接訪問您的ivars,除非在initdealloc之間。使用訪問器。這會讓你的大部分問題消失。

其次,不要在applicationDidBecomeActive調用setupDistance。你的意思是在applicationDidFinishLaunchingWithOptions:中調用它。但更好的是,在Metrics init期間初始化它。爲什麼在應用程序委託中有此內部Metrics的詳細信息?

1

當它從睡眠回來打電話來設置在距離再次applicationDidBecomeActive將被調用。你調用一個屬性(.test)而不是分配是很奇怪的。測試在做什麼工作?它應該是一種方法嗎?它在做什麼?

此外,在一個單身你不得不超載一些事情。這是我使用的單例模板。

static MySingleton *sharedInstance = nil; 

@implementation MySingleton 

#pragma mark - 
#pragma mark class instance methods 

#pragma mark - 
#pragma mark Singleton methods 

+ (MySingleton*)sharedInstance 
{ 
    @synchronized(self) 
    { 
     if (sharedInstance == nil) 
      sharedInstance = [[MySingleton alloc] init]; 
    } 
    return sharedInstance; 
} 

+ (id)allocWithZone:(NSZone *)zone { 
    @synchronized(self) { 
     if (sharedInstance == nil) { 
      sharedInstance = [super allocWithZone:zone]; 

     return sharedInstance;  // assignment and return on first allocation 

     } 
    } 

    return nil; // on subsequent allocation attempts return nil 
} 

- (id)copyWithZone:(NSZone *)zone 
{ 
    return self; 
} 

- (id)retain { 
    return self; 
} 

- (unsigned)retainCount { 
    return UINT_MAX;  // denotes an object that cannot be released 
} 

- (void)release { 
    //do nothing 
} 

- (id)autorelease { 
    return self; 
} 

@end 
+2

梅;你不必爲了創建一個單例而重載任何東西。我從來沒有打擾,它工作正常;覆蓋保留/釋放/自動釋放等,只是防禦應該修復的錯誤代碼。 – bbum

+0

同意bbum。我一直使用這個問題中的模式。設計你的類要好得多,以便它可以在非單例上下文中使用,而不是阻止人們在非單例上下文中實例化它。 – JeremyP

+0

我認爲你需要決定它是單身人士,實例班還是兩者。如果它是一個單身人士,那麼把它變成一個,並且避免很難找到錯誤 - 你也可以在發佈等中添加日誌錯誤(或調試斷言)語句...如果你想找到那些不恰當地調用它的人。如果你不覆蓋,你就沒有機會找到不恰當地使用類的代碼(作爲非單例),這會導致更難找到錯誤。 – bryanmac