变量失去了它的分配

时间:2013-06-07 18:13:26

标签: ios objective-c cocoa

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

我在viewDidLoad方法中设置变量,NSLog返回_myUser.email_myUser的预期结果。

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

我搜索了整个应用,我设置_myUser的唯一位置是viewDidLoad,所以不是我在其他任何地方取消它

修改:如果我从[self myOtherMethod]的最末端致电ViewDidLoad,则NSLog将起作用,但不会从任何其他方法内部发起。

edit2 当我做同样的事情时,它适用于应用的其他部分

UserNSManagedObject个对象 ModelNSObject,其中包含我的所有模型查询。

崩溃是一个简单的(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);
}

3 个答案:

答案 0 :(得分: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。已分配但未初始化的对象是危险的;当你试图使用它时可能会发生任何事情。

在此代码中,它没有任何区别,因为您立即将您刚刚创建的用户对象(但未初始化)替换为您从[_model getCurrentUser]获得的用户对象。

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

这也是为什么说出任何意义没有意义的原因:

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

第一行创建一个与任何事物无关的新User对象,并在_myUser变量中存储对它的引用,然后第二行立即通过引用另一个User对象(您从模型中获取的“当前用户”)替换对该对象的引用。一个变量,两个对象。

  

崩溃是一个简单的(lldb)

(lldb)”不是一种崩溃;这是调试器的提示。你需要在提示上方查看它是什么类型的崩溃。

在导航器中查看堆栈跟踪并查看崩溃发生的代码的确切位置也可能有所帮助。

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

  

最后retain成了诀窍......

然后你没有使用ARC。您无法在ARC下发送retain条消息,因此如果您发送retain消息并且您的构建成功,则证明您没有使用ARC。

反过来,这表明问题是什么:您将从getCurrentUser获得的User对象分配给您的实例变量,但是因为您没有保留它或将其分配给{{1}属性,它从你身下消失了,既然你还在抓住它,那么当你试图使用那个死对象时,你会崩溃。

我建议打开ARC。然后,您不需要(或能够)保留该对象;只是将它分配给一个实例变量,例如strong,就可以保持对象的存活。

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

答案 1 :(得分:0)

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

答案 2 :(得分:-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);
    }