0

洞察なしでWebを検索した後、次のコードで何が問題なのかを説明できるよう、ここで問題を投稿することにしました。 Objective-Cではシングルトンデザインパターンを実装できませんでした。私は(プロパティリストの各エントリは、辞書そのものである場合)、インターネット上のパターンを実装し、いくつかのコードを発見し、plistファイルから開始された辞書を追加するために、それを少し修正:[CFDictionary objectForKey:]:解放されたインスタンスにメッセージが送信される

@interface UnitManager : NSObject { 
NSString *someProperty; 
NSDictionary *factors; 
} 

@property (nonatomic, retain) NSString *someProperty; 
@property (nonatomic, retain) NSDictionary *factors; 

+ (id) sharedUnitManager; 

@end 

// implementation file 
#import "Unit.h" 

#define MARGIN 20 

static UnitManager *unitManager = nil; 

@implementation UnitManager 

@synthesize someProperty; 
@synthesize factors; 

#pragma mark Singleton Methods 

+ (id)sharedUnitManager { 
    @synchronized(self) { 
     if(unitManager == nil) 
      unitManager = [[super allocWithZone:NULL] init]; 
    } 
    return unitManager; 
} 
+ (id)allocWithZone:(NSZone *)zone { 
    return [[self sharedUnitManager] retain]; 
} 
- (id)copyWithZone:(NSZone *)zone { 
    return self; 
} 
- (id)retain { 
    return self; 
} 
- (unsigned)retainCount { 
    return UINT_MAX; //denotes an object that cannot be released 
} 
- (void)release { 
    // never release 
} 
- (id)autorelease { 
    return self; 
} 
- (id)init { 
    if (self = [super init]) { 
     someProperty = [[NSString alloc] initWithString:@"Default Property Value"]; 

     // get path to file that stores category order 
     NSString *path = [[NSBundle mainBundle] pathForResource:@"factors" ofType:@"plist"]; 

     factors = [NSDictionary dictionaryWithContentsOfFile:path]; 


    } 
    return self; 
} 
- (void)dealloc { 
    // Should never be called, but just here for clarity really. 
    [someProperty release]; 
    NSLog(@"should NEVER GET HERE!"); 
    [factors release]; 
    [super dealloc]; 
} 

@end 

その後、いくつかのコードでは、後でシングルトンオブジェクトの辞書にアクセスしようとしますが、最初はうまく動作しますが、2回目に割り当て解除されたメモリにアクセスします。

- (void) someFunction { 
... 

    NSString *str = [[[[UnitManager sharedUnitManager] factors] objectForKey:category] objectForKey:name]; 
... 
... 



} 

Iを取得メッセージは

2011-09-12 17である:39:44.567試験[7837:B603] - [CFDictionary objectForKey:]:割り当て解除インスタンスに送信されたメッセージ0x4d565e0 *

とメモリ・トレース:

(GDB)情報のmalloc履歴0x5c73300 のAlloc:ブロックアドレス:0x05c73300長さ:48 スタック - のpthread:フレームの0xac2bd2c0数:44

0. 0x92573993 in malloc_zone_malloc 
1. 0xebe87d in _CFRuntimeCreateInstance 
2. 0xebe47a in CFBasicHashCreate 
3. 0xf81e44 in __CFDictionaryCreateTransfer 
4. 0xeed3ff in __CFBinaryPlistCreateObject2 
5. 0xee2009 in __CFTryParseBinaryPlist 
6. 0xee1a48 in _CFPropertyListCreateWithData 
7. 0xee19ba in CFPropertyListCreateWithData 
8. 0xee194f in CFPropertyListCreateFromXMLData 
9. 0x791e34 in _NSParseObjectFromASCIIPropertyListOrSerialization 
10. 0x7913d5 in +[NSDictionary(NSDictionary) newWithContentsOf:immutable:] 
11. 0xf067bf in -[__NSPlaceholderDictionary initWithContentsOfFile:] 
12. 0x791308 in +[NSDictionary(NSDictionary) dictionaryWithContentsOfFile:] 
13. 0xcb38 in -[UnitManager init] at Unit.m:54 
14. 0xc833 in +[UnitManager sharedUnitManager] at Unit.m:25 
15. 0xe03a in -[Unit factor] at Unit.m:226 
16. 0x39c9 in -[MainViewController updateTextFields] at MainViewController.m:113 
17. 0x4037 in -[MainViewController refresh] at MainViewController.m:229 
18. 0x79c669 in _nsnote_callback 
19. 0xf879f9 in __CFXNotificationPost_old 
20. 0xf0693a in _CFXNotificationPostNotification 
21. 0x79220e in -[NSNotificationCenter postNotificationName:object:userInfo:] 
22. 0x79e551 in -[NSNotificationCenter postNotificationName:object:] 
23. 0x62f7 in -[MainViewController changeUnit:] at MainViewController.m:447 
24. 0x2a4fd in -[UIApplication sendAction:to:from:forEvent:] 
25. 0xba799 in -[UIControl sendAction:to:forEvent:] 
26. 0xbcc2b in -[UIControl(Internal) _sendActionsForEvents:withEvent:] 
27. 0xba750 in -[UIControl sendActionsForControlEvents:] 
28. 0xfa59b in -[UISegmentedControl setSelectedSegmentIndex:] 
29. 0xff39d in -[UISegmentedControl touchesBegan:withEvent:] 
30. 0x4ed41 in -[UIWindow _sendTouchesForEvent:] 
31. 0x2fc37 in -[UIApplication sendEvent:] 
32. 0x34f2e in _UIApplicationHandleEvent 
33. 0x11e8992 in PurpleEventCallback 
34. 0xf90944 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ 
35. 0xef0cf7 in __CFRunLoopDoSource1 
36. 0xeedf83 in __CFRunLoopRun 
37. 0xeed840 in CFRunLoopRunSpecific 
38. 0xeed761 in CFRunLoopRunInMode 
39. 0x11e71c4 in GSEventRunModal 
40. 0x11e7289 in GSEventRun 
41. 0x38c93 in UIApplicationMain 
42. 0x2639 in main at main.m:14 
43. 0x25b5 in start 

は、誰かがここで何が起こっているかを説明できますか?なぜ私が辞書にアクセスできないのか分かりません。私はそれが使用されている2回目の辞書の割り当てを解除するものは見ません。

はあなたが自動解放オブジェクトにインスタンス変数を設定している

答えて

5
factors = [NSDictionary dictionaryWithContentsOfFile:path]; 

AA、あなたのすべてをありがとうございます。プールが排水されると、factorsへの次のメッセージはBOOMになる可能性があります。

このメソッドは、フレームワークAPIのすべてのメソッドの標準ルールに従います。 policies guideを参照してください。

ドキュメントは、メソッドごとに共通ルールを繰り返さないようにすばらしい長さになります。ガイドを読んでいない場合は、それぞれの方法がどのように機能するかを理解できません。

「人間に魚を与えれば、彼は一日食べるだろう。人間に魚を釣ることを教え、彼は生涯にわたって自分自身を養う」というアプローチです。

+0

私の質問にお答えいただきありがとうございます。その行には、autoreleaseステートメントはありません。マニュアルではNSDictionaryを検索しましたが、オートレリースされたオブジェクトを返すことについては何も言及していません。それが本当にオートリリースされたことをどうやって知っていますか? – aaragon

+2

これはフレームワークAPIのすべてのメソッドの標準ルールに従っているためです。ポリシーガイドを参照してください:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH – bbum

関連する問題