проблема с делегатом Тема 1: Программа получает неверный сигнал "EXC_BAD_ACCESS" - PullRequest
0 голосов
/ 18 июня 2011

в методе applicationDidEnterBackground моя программа получает ошибочный сигнал «EXC_BAD_ACCESS». на [self-offOffline]; линия

-(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 Ответ

2 голосов
/ 18 июня 2011

Некоторые из ваших переменных автоматически высвобождаются, поэтому их нельзя освобождать (они будут высвобождены автоматически):

  • data
  • request
  • url
  • response
  • err
  • responseData

Плюс, идентификатор пользователя принадлежит другому объекту (theController)

Вы вызываете release только тогда, когдаВы вызываете

  • alloc
  • new
  • copy
  • явно

для переменной или любого методаначиная с 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 по управлению памятью (или любой ресурс по этой теме).Постарайтесь прочитать это внимательно, это не очень сложно, но самое запутанное, если вы не сделаете это правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...