0


0

EXC_BAD_ACCESを取得する理由

Hey. 私はTwitterアプリケーションに取り組んでおり、かなり長い間EXC_ BAD_ ACCESSエラーで立ち往生しています。 EXC_ BAD_ ACCESSはメモリの問題であることは知っていますが、問題の場所を特定することはできません。 これが私のコードサンプルです。

- (void)viewDidLoad {
   [super viewDidLoad];

   NSString *path = @"/Volumes/Schools/BHS/Student/740827/Documents/Forrest McIntyre CS193P/Presence2";
   NSArray *propList = [NSArray arrayWithContentsOfFile:[NSBundle pathForResource:@"TwitterUsers" ofType:@"plist" inDirectory:path]];

   people = [[NSMutableArray alloc]init];

   for (NSString *name in propList) {
     Person *p = [[Person alloc] initWithUserName: name];
     [people addObject: p];
     [p release];
   }
   // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
   // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

例外は、コメントの後の最後の中括弧にスローされます。 私はそれが本当にどこかにforループでスローされますが、終了するとすぐに表示されると信じています。

Personの実装ファイルは次のとおりです。

@implementation Person
@synthesize image;
@synthesize username;
@synthesize displayName;
@synthesize statusArray;

-(id)initWithUserName:(NSString *)userName {
 if(self = [super init])
 {
  self.username = userName;
  NSDictionary *info = [TwitterHelper fetchInfoForUsername:userName];
  self.displayName = [info objectForKey:@"name"];
  NSLog([NSString stringWithFormat:@"%@",[info objectForKey:@"profile_image_url"]]);
  NSString *imageURL2 = [NSString stringWithFormat:@"%@",[info objectForKey:@"profile_image_url"]];
  self.image = [UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString: imageURL2]]];
  [info release];
  self.statusArray = [TwitterHelper fetchTimelineForUsername:userName];
 }
 return self;
}
@end

助けてくれてありがとう

編集:PersonListViewController(ViewDidLoadを含むクラス)のヘッダーファイルです。 これは、人々がどこから来ているかを示すためです。

@interface PersonListViewController : UITableViewController {
    NSMutableArray *people;
}

@end

8 Answer


9


「propList」や「path」を保持することは決してないので、それらを解放するべきではありません。

ただし、「人々」を解放する必要があります

メモリ管理の概要については、http://developer.apple.com/iPhone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html [メモリ管理プログラミングガイド]を参照してください

すばやく修正するには、静的アナライザーを試してください。


3


私は問題がここにあると思います:

[propList release];

`arrayWithContentsOfFile`を使用してpropListを作成したため、リリースする必要はありません-自動的にリリースされます。 自動リリースは、実際に手動でリリースしたものをリリースしようとしているため、実際にエラーの原因となっています。

ETA:cobbalが述べたように、 `path`を解放する必要もありません。


1


EXC_BAD_ACCESSのデバッグはデバッグが困難です。 これは、すでにリリースされているオブジェクトにメッセージが送信されるときに発生します。 NSZombiEnabled環境変数をオンにして、Objective-C環境が割り当て解除されたオブジェクトを「追跡」できるようにすることで、この一般的なエラーの原因を見つける必要があります。 これを使用すると、エラーが発生したときに、コールスタックを調べることでエラーが発生した場所を特定できます。 それがどこでリリースされたかはわかりませんが、少なくともそれはあなたを近づけます。

ここではセットアップしていませんが、エラーへのポインタを渡すと、オブジェクトがゾンビ/ダミーとして保持されなくなります。

結論として、リリースすることを意図している変数を確認し、必要に応じて保持する必要があります。

AppleによるこのテクニカルQ&Aは、http://developer.apple.com/mac/library/qa/qa2004/qa1367.html [EXC_BAD_ACCESSを使用したバグの検索]でヒントを提供しています。


1


一つには、あなたの例ではこれらのどちらも必要ありません:

 [path release];
 [propList release];

なぜなら

`path`は文字列リテラルです(常に存在します)

「propList」は自動リリースされます


1


EXC_BAD_ACCESSエラーが発生した場合は、通常、解放されたオブジェクトにメッセージを送信しようとしています。 これらを追跡する* BEST *方法はhttp://www.cocoadev.com/index.pl?NSZombieEnabled [NSZombieEnabled]を使うことです。

これは実際にはオブジェクトを解放するのではなく、「ゾンビ」としてそれを包み込み、その中に通常は解放されているというフラグを立てることで機能します。 こうすれば、再度アクセスしようとしても、エラーが発生する前の状態を把握しています。このわずかな情報で、通常は問題の原因を突き止めることができます。

デバッガが有用な情報を見つけ出すときに、バックグラウンドスレッドで特に役立ちます。

*注意すること*非常に重要*ただし、これはデバッグコードにのみ含まれ、配布コードには含まれていないことを100%確認する必要があるということです。 何もリリースされていないので、あなたのアプリはリークしてリークしてリークします。 これをするように私に思い出させるために、私は私のappdelegateにこのログを入れます:

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
  NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");

正確な行を見つける手助けが必要な場合は、ビルド&実行(* CMD-R )の代わりにビルド&デバッグ( CMD-Y *)を実行してください。 アプリがクラッシュすると、デバッガはどの行をNSZombieEnabledと組み合わせて正確に表示するか、正確な理由を見つけることができます。


0


http://www.cocoadev.com/index.pl?NSZombieEnabledは、EXC_BAD_ACCESSのバグを追跡するのに役立ちます。 オブジェクトが「解放」されたときに割り当てを解除する代わりに、オブジェクトがゾンビ状態になり、その後アクセスされたときに例外が発生します。 ふるいのようにメモリをリークするため、このフラグが設定されたコードを決してリリースしないようにしてください。


0


self.editButtonItemとは何ですか? .hファイルに表示されません


0


いくつかあります。

  • 「initWithUserName:」では、取得しないメソッドから情報を取得しています alloc / copy / createが含まれます。 さらに、明示的に保持することはありません。 しかし、あなたはそれを解放します。 これは、 `fetchInfoForUsername:`がCocoaメモリ管理ルールに従って期待どおりに結果を自動解放すると仮定すると問題となります。

  • イニシャライザでプロパティアクセサを使用するのは、次の理由から不適切な形式と見なされます。 半分ベイクされたインスタンスに対してKVO通知が送信される可能性があります。