0

我无法弄清楚为什么会出现此错误,并希望得到一些指导。

我在viewDidLoad方法中设置一个变量,并从和NSLog返回预期结果。_myUser.email_myUser

现在,当我以任何方法调用该_myUser变量时,(IBAction)它总是会使应用程序崩溃。我认为是因为它失去了分配。否则我无法解释为什么如果在其他任何地方执行它会使应用程序崩溃。但话又说回来......我正在做我所知道的一切,以确保该变量在整个应用程序中可用和设置。

我已经搜索了整个应用程序,我设置的唯一位置_myUser是在 中viewDidLoad,所以这并不是说我在其他任何地方都取消了它

编辑:如果我从遗嘱的最后调用而[self myOtherMethod]不是从任何其他方法内部调用。ViewDidLoadNSLog

edit2当我做同样的事情时,它可以在应用程序的另一部分工作

User是一个NSManagedObject对象 Model是一个NSObject我有我所有的模型查询的地方。

崩溃很简单(lldb)

@property (strong, nonatomic) User* myUser;

- (void)viewDidLoad
{

    [super viewDidLoad];

    _model = [[model alloc]init];
    _myUser = [User alloc]; // I can do this or not do it and it gives me the same result
    _myUser = [_model getCurrentUser];

     NSLog(@"First: %@",_myUser.email);
}
- (void) myOtherMethod {
NSLog(@"Second: %@",_myUser.email);
}
4

3 回答 3

3
_myUser = [User alloc]; // I can do this or not do it and it gives me the same result
_myUser = [_model getCurrentUser];

切勿[SomeClass alloc]在未立即发送结果init(或其任何变体)消息的情况下打电话。已分配但未初始化的对象是危险的;当您尝试使用它时,任何事情都可能发生。

在这段代码中,它没有任何区别,因为您立即将刚刚创建(但未初始化)的 User 对象替换为您从[_model getCurrentUser].

变量和对象是两个不同的东西。该变量是您在其中声明此属性的任何对象的一部分(看起来像某种视图控制器),并且是一个容器,其中包含对另一个对象的引用,该对象是您从模型中获取的 User 对象。变量没有“失去分配”;用户对象是。

这也是为什么这样说没有意义的原因:

_myUser = [[User alloc] init]; //This statement is unnecessary!
_myUser = [_model getCurrentUser];

第一行创建了一个与任何东西都没有任何关系的新用户对象,并将对它的引用存储在_myUser变量中,然后第二行立即用对不同用户对象的引用替换对该对象的引用——您从模型中获得的“当前用户”。一个变量,两个对象。

崩溃很简单(lldb)

“<code>(lldb)” 不是一种崩溃;这是调试器的提示。您需要查看提示上方以查看它是哪种崩溃。

查看 Navigator 中的堆栈跟踪并准确查看崩溃发生在代码的哪一行也可能会有所帮助。

[已添加]bt如果导航器中没有任何内容,或者输入该提示。(显然,根据我见过的其他几个 SO 问题,LLDB 在没有 Xcode 注意到的情况下启动是一个从 10.8.4 开始出现的错误。)

最后成功了retain……

那么你没有使用ARC。ARC下不能发送retain消息,所以如果可以发送retain消息并且构建成功,就证明你没有使用ARC。

反过来,这表明了问题所在:您将从中获得的 User 对象分配给了getCurrentUser您的实例变量,但是由于您没有保留它或将其分配给strong属性,因此它在您之下消失了,并且由于您仍然握着它,稍后当您尝试使用那个死物时,您坠毁了。

我建议打开 ARC。然后,您将不需要(或能够)保留该对象;只需将其分配给一个实例变量,这样_myUser就可以使对象保持活动状态。

一种选择是您选择的解决方案(您retain自己的对象);另一种是将对象分配给myUser属性(self.myUser)而不是_myUser实例变量。只要您不使用ARC,仅分配给实例变量就不会保留对象;赋值给一个strong属性,就像retain你自己给对象赋值一样。

于 2013-06-08T01:31:29.513 回答
0

一个不错的经验法则,特别是对于新的 Objective-C 程序员来说,总是使用属性而不是实例变量,并且只在 getter 和 setter 中引用 _instanceVariable。

于 2013-06-07T19:09:30.500 回答
-6
- (void)viewDidLoad
{

    [super viewDidLoad];

    _model = [[model alloc]init];

    self._myUser = [[_model getCurrentUser] retain];

     NSLog(@"First: %@",self._myUser.email);
}
- (void) myOtherMethod {
NSLog(@"Second: %@",self._myUser.email);
}

或者

- (void)viewDidLoad
    {

        [super viewDidLoad];

        _model = [[model alloc]init];

        _myUser = [[_model getCurrentUser] retain]; // or copy if you owerdrive copyWithZone: metod

         NSLog(@"First: %@",_myUser.email);
    }
    - (void) myOtherMethod {
    NSLog(@"Second: %@",_myUser.email);
    }
于 2013-06-07T18:46:54.380 回答