0

我知道标题可能听起来有点奇怪,但问题也是如此。

我几乎在整个开发过程中都在模拟器上测试我的应用程序,我确实偶尔在真实设备上测试过一次以确保。但是现在我快要完成一个问题了。

每当我执行登录时,我的整个应用程序都会崩溃,说用户名和密码变量已被释放......

这是我的申请流程:

打开应用程序时,它会检查用户名和密码是否已保存或注释

- (void)checkIfPreviouslyLoggedIn:(BOOL)didLogin andLogin:(BOOL)doLogin {
     // some logic to get it out of the keychain
     NSLog(@"checkIfPreviouslyLggedIn: ACCOUNT %@ / %@", tmpUsername, tmpPassword);

     // RETURN: checkIfPreviouslyLggedIn: ACCOUNT  /
}

之前什么都没有保存,没什么大不了的,用户只需输入帐户并按登录即可

- (void)loginWithUsername:(NSString *)username andPassword:(NSString *)password {
      NSLog(@"loginWithUsername: ACCOUNT %@ / %@", username, password);
      // RETURN: loginWithUsername: ACCOUNT testUser / password

      // save it for later use
      _username = username;
      _password = password;

      NSLog(@"loginWithUsername: ACCOUNT %@ / %@", _username, _password);
      // RETURN: loginWithUsername: ACCOUNT testUser / password

      // Attach a notification handler
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginCheck:) name:@"LoginCheck" object:nil];

      // call the web API
      [self doRequestFromLocation:@"/groups" withPostType:@"GET" andData:nil whichTriggersNotification:@"LoginCheck"];
}

很酷,用户名和密码都很好地记录了,到目前为止一切都很好,doRequestFromLocation 基本上是一个队列类型的东西,我可以发送任意数量的请求,它会一个一个地处理它们

- (void)doRequestFromLocation:(NSString *)location withPostType:(NSString *)type andData:(NSData *)data whichTriggersNotification:(NSString *)notification {
      NSLog(@"doRequestFromLocation: ACCOUNT %@ / %@", _username, _password);
      // RETURN: doRequestFromLocation: ACCOUNT testUser / password
} 

然后它转到 doRequest 方法,该方法执行实际的数据请求,我再次在那里记录我的用户名,它返回正确的用户名。

NSLog(@"doRequest: ACCOUNT %@ / %@", _username, _password);

在此之后,一切都变得非常糟糕,当请求完成时,调用 loginCheck()

- (void)loginCheck:(NSNotification *)notification {
    NSLog(@"loginCheck: ACCOUNT %@ / %@", _username, _password);
}

在这里,我的 _username 和 _password 被释放,甚至在实际通话之前我检查了用户名和密码,它们仍然很好。

所以不知何故(神奇地)这两个变量被无缘无故地释放了。请注意,_username 和 _password 仅在 loginWithUsername 中设置,它们不会在我的应用程序中的任何地方更改。

2012-06-04 13:33:28.001 coop[5060:707] * -[CFString respondsToSelector:]:消息发送到已释放实例 0x1099fc40 2012-06-04 13:33:28.648 coop[5060:707] * -[CFString _cfTypeID]:发送到已释放实例 0x1099fc40 的消息

可能是什么导致了这种情况,我添加了多个断点,只是意识到在调用和 loginCheck() 之间的某个地方它们消失了。

4

2 回答 2

1

问题在这里:

 // save it for later use
      _username = username;
      _password = password;

您的变量_username_password没有保留,这就是它们被自动释放的原因。

在 NON-ARC 情况下,将它们声明@property(retain)为 ARC,对于 ARC,@property(strong)使用:

self._username = username;
self._password = password;

现在您拥有内存的所有权,现在您必须在完成后释放它。

于 2012-06-04T05:46:48.953 回答
1

请检查您是如何在头文件中声明属性(_username 和 _password)的。如果它没有被声明为

@property (nonatomic, retain) NSString * _username;
@property (nonatomic, retain) NSString * _password;

那么您的属性将自动释放。因此,稍后当您尝试访问此属性时,您会收到它们已释放的消息。

此外,当您在头文件中将变量声明为属性时,请使用“self.”访问它们。

请仅在您完成后解除分配您的属性,无需进一步访问此属性。

请让我知道是否需要更多帮助

于 2012-06-04T05:56:13.167 回答