委托问题线程1:程序收到错误信号“EXC_BAD_ACCESS”

时间:2011-06-18 11:27:55

标签: iphone objective-c xcode

在applicationDidEnterBackground方法中,我的程序收到错误信号“EXC_BAD_ACCESS”错误。在[self goingOffline];线

-(void)goingOffline
    {
        NSLog(@"going offline");
        profileViewController * theController;
        NSArray * viewControllers = rootController.viewControllers;
        for ( UIViewController * viewController in viewControllers ) {
            if ( [viewController isMemberOfClass:[profileViewController class]] ) {
                theController = (profileViewController *)viewController;;
            }
        }

    NSString *userID = theController.userId;

    NSMutableData *data = [NSMutableData data]; 

    NSMutableString *userString = [[NSMutableString alloc] initWithFormat:@"id=%@", userID];

    //NSLog(userString);
    //NSLog(numberString);

    [data appendData:[userString dataUsingEncoding:NSUTF8StringEncoding]];

    NSURL *url = [NSURL URLWithString:@"http://www.blah.net/offline.php"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:data];

    NSURLResponse *response;
    NSError *err;

    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
    NSLog(@"responseData: %@", responseData);

    [userID release];
    [data release];
    [request release];
    [url release];
    [userString release];
    [response release];
    [err release];
    [responseData release];
}


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.
    [self.window addSubview:rootController.view];
    [window makeKeyAndVisible];

    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
     */

    [self goingOffline];
}

1 个答案:

答案 0 :(得分:2)

您的一些变量是自动释放的,因此不得发布(它们会自动重新发布):

  • 数据
  • 请求
  • URL
  • 响应
  • ERR
  • responseData

另外,userID属于另一个对象(theController)

您只能在致电

时致电发布
  • 的alloc
  • 复制
  • 保留

显式地对变量或任何以copy / new开头的方法(copyWithZone:,newWithFoo :) ...

所以替换

[userID release];
[data release];
[request release];
[url release];
[userString release];
[response release];
[err release];
[responseData release];

通过

[userString release];

因为userString是唯一明确分配的变量。

这将解决问题,您的对象不应泄漏。

此外,控制器似乎是一个实例变量,因此您可能希望对其拥有所有权:

        if ( [viewController isMemberOfClass:[profileViewController class]] ) {
            theController = [(profileViewController *)viewController retain];
        }

或者,如果它是使用retain

合成的属性
        if ( [viewController isMemberOfClass:[profileViewController class]] ) {
            self.theController = (profileViewController *)viewController;
        }

而不是

        if ( [viewController isMemberOfClass:[profileViewController class]] ) {
            theController = (profileViewController *)viewController;;
        }

(我刚刚意识到你在行尾也有两个分号)

并添加你的dealloc方法:

-(void) dealloc
{
 //...release the other objects you have ownership on
 [theController release];
 [super dealloc];
}

如果您是Objective-C的新手,您可能需要查看Apple documentation about memory management(或此主题的任何资源)。试着仔细阅读,这不是很困难,但如果你做得不对,这是最令人困惑的事情。