Jul 292012
 

Objective-CでARCをONにした状態で、UIButtonを設置。ボタンをタップするとメソッドが呼び出されずEXC_BAD_ACCESSとなる場合の解決法。Xcodeの問題でもiOSの問題でもない。ARCが主流になると新たな問題も出て来る一例。

基本の設置コード

ボタンを画面に一つ貼付けるコード。タップするとログを出す。

UIViewControllerのインスタンスを生成し、viewControllerのviewをwindowに貼付ける。viewControllerではviewDidLoadの時点でUIButtonのインスタンスをviewに貼付ける。

FTAppDelegate.m

#import "FTButtonViewController.h"
@implementation FTAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    FTButtonViewController *c = [[FTButtonViewController alloc] init];
    [self.window addSubview:c.view];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

FTButtonViewController.m

- (void)tapped:(id)sender
{
    NSLog(@"thx tapped");
}
- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view.
    UIButton * button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button setFrame:CGRectMake(50, 100, 100, 20)];
    [button addTarget:self action:@selector(tapped:) forControlEvents:UIControlEventTouchUpInside];
    [button setTitle:@"hello" forState:UIControlStateNormal];
    [self.view addSubview:button];
}

このボタンをタップするとメソッドが呼び出されずEXC_BAD_ACCESSとなる。ARCでは、この例の場合AppDelegateでviewはaddSubViewされているためretainCountは増えているが、viewControllerをstrong(retain)参照するプロパティが存在しない上、代入されていない。既にメモリ解放されている。

解決法

viewControllerがメモリから解放されないようにstrong(retain)参照(強い参照)を作成しておく。

#import "FTButtonViewController.h"
@implementation FTAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    FTButtonViewController *c = [[FTButtonViewController alloc] init];
    [self.window addSubview:c.view];
    self.controller = c;//UIViewControllerをstrong(retain)参照するメンバ
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

参考サイト

http://stackoverflow.com/questions/9103705/uibutton-touches-up-ibaction-causing-exc-bad-access-with-arc

コメント

個のコメント

Powered by Facebook Comments

 Posted by at 15:43

Sorry, the comment form is closed at this time.