2

アプリケーションを作成していますが、EXC_BAD_ACCESS エラーが発生します。


コード

@interface DNProjectsCategory : DNCategory {
  NSArray *projects;
}

@property(nonatomic, retain) NSArray *projects;

@end

と:

@implementation DNProjectsCategory
@synthesize projects;

// MEM

- (void)dealloc {
  [projects release];
  
  [super dealloc];
}

// INIT.
- (id)init {
  if (self = [super init]) {
    title = NSLocalizedString(@"PROJECTS", nil);
    isSubCategory = NO;
    
    // Initialize projects
    //!!LINE 32 IS HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    projects = [NSArray arrayWithContentsOfFile:DNPROJECTSFILE];
  }
  
  return self;
}

// CATEGORIES

- (NSArray *)subCategories {
  NSMutableArray *projectsArray = [[[NSMutableArray alloc] init] autorelease];
  
  for (NSDictionary *project in projects) {
    DNCategory *projectCategory = [[DNCategory alloc] initWithTitle:[project valueForKey:@"title"]
                                                      subCategories:nil
                                                      isSubCategory:YES];
    
    [projectsArray addObject:projectCategory];
    [projectCategory release];
  }
  
  return projectsArray;
}

DNPROJECTSFILE の内容

http://gist.github.com/618628を参照してください。


コンソールと計器

これは、実行時にコンソールに表示される内容です (NSZombie が有効になっている場合)。

run
[Switching to process 41257]
Running…
2010-10-09 23:32:36.899 Done[41257:a0f] *** -[CFString isKindOfClass:]: message sent to deallocated instance 0x1001caab0
sharedlibrary apply-load-rules all

インスツルメンツが NSZombie テストで言っていることは次のとおりです。

ゾンビメッセージ

Objective-C メッセージが、アドレス 0x10012af80 の割り当て解除されたオブジェクト (ゾンビ) に送信されました。

 

スタックトレース

   0 CoreFoundation _CFRuntimeCreateInstance
   1 CoreFoundation __CFStringCreateImmutableFunnel3
   2 CoreFoundation CFStringCreateWithBytes
   3 CoreFoundation _uniqueStringForCharacters
   4 CoreFoundation getString
   5 CoreFoundation parseXMLElement
   6 CoreFoundation parseXMLElement
   7 CoreFoundation parseArrayTag
   8 CoreFoundation parseXMLElement
   9 CoreFoundation parsePListTag
  10 CoreFoundation parseXMLElement
  11 CoreFoundation _CFPropertyListCreateFromXMLStringError
  12 CoreFoundation _CFPropertyListCreateWithData
  13 CoreFoundation CFPropertyListCreateFromXMLData
  14 Foundation _NSParseObjectFromASCIIPropertyListOrSerialization
  15 Foundation +[NSArray(NSArray) newWithContentsOf:immutable:]
  16 Foundation +[NSArray(NSArray) arrayWithContentsOfFile:]
  17 Done -[DNProjectsCategory init] /Users/rsonic/Developer/Done/DNProjectsCategory.m:32
  18 Done -[DNBindingsController categories] /Users/rsonic/Developer/Done/DNBindingsController.m:18
  19 Foundation -[NSObject(NSKeyValueCoding) valueForKey:]
  20 Foundation -[NSObject(NSKeyValueCoding) valueForKeyPath:]
  21 AppKit -[NSBinder valueForBinding:resolveMarkersToPlaceholders:]
  22 AppKit -[NSArrayDetailBinder _refreshDetailContentInBackground:]
  23 AppKit -[NSObject(NSKeyValueBindingCreation) bind:toObject:withKeyPath:options:]
  24 AppKit -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:]
  25 AppKit loadNib
  26 AppKit +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:]
  27 AppKit +[NSBundle(NSNibLoading) loadNibNamed:owner:]
  28 AppKit NSApplicationMain
  29 Done main /Users/rsonic/Developer/Done/main.m:13
  30 Done start

質問

このダブルリリースを修正する方法が本当にわかりません。私が知る限り、projects以外の場所では変数を解放しませんdealloc。誰か助けてくれませんか?ありがとう。

4

1 に答える 1

6

アクセサーを使用していないため、プロジェクトは保持されません。init メソッドの 2 つの選択肢:

projects = [[NSArray arrayWithContentsOfFile:DNPROJECTSFILE] retain];

また

self.projects = [NSArray arrayWithContentsOfFile:DNPROJECTSFILE];

@property(nonatomic, retain) NSArray *projects;

- (NSArray *)projectsプロパティは、ゲッターとセッターの2 つのメソッドを「作成」- (void)setProjects:(NSArray*)a;します。プロパティ宣言で記述した保持ステートメントは、セッターにのみ適用されます。projects = foo;セッターで変数を直接設定した場合は使用されません。
ただし、動的に作成されたセッターであるself.projects = foo;と同等です。 セッターは次のようになります。[self setProject:foo]

- (void)setProjects:(NSArray*)anArray {
    [anArray retain];
    [projects release];
    projects = anArray;
}

したがって、セッターを使用すると、arrayWithContentsOfFile: から取得した自動解放された NSArray が保持されます。
「alloc」、「copy」、「retain」、または new で始まるものではない、Objective C で行うすべての呼び出しは、自動解放されたオブジェクトを返します。それらを後で使用する場合 (つまり、それらが作成されたメソッドを離れた後) は、それらを保持する必要があります。

たぶん、 Apple メモリ管理ガイドをもう一度見てみたいと思うかもしれません。

于 2010-10-09T21:53:39.293 に答える