@implementation, vars and ARC

2019-09-10 06:36发布

问题:

In my project There is a controller A with next code:

@implementation NKAddPostViewController
int _characterCounter = 512;
...

I change this variable in code, that it value is 400. Than i do popViewControllerAnimated.

But when i go to this controller again the value still 400. In viewWillAppear, viewDidLoad it still 400. Why? It seems that controller A is retained, but when i debug properties in viewDidLoad, they are nill until they are initialized again.

Here is the implementation of transfer, so nothing retain controllerA:

NKAddPostViewController *aContr = [NKAddPostViewController new];
[self.navigationController aContr animated:YES];

2 questions:

  1. So why _characterCounter retains?
  2. Why when controller initializing the line int _characterCounter = 512; don't assign 512 to _characterCounter?

回答1:

In your comments you say "3) implement like ivar in implementation and immediately assign value. 3-rd way is easier and faster"

3rd way is wrong. "ivar in implementation" is actually a private static variable, and does not do what you want.

You can create a private category and define a new instance variable there:

In your .m file, add this:

@interface NKAddPostViewController()
{
  int _characterCounter;
}

- (instancetype) init;
{
  self = [super init]; 
  if (!self) 
    return nil;
  _characterCounter  = 512;
}

That should do what you want.



回答2:

What you did is declare a global variable. It's not tied to the class at all, and has absolutely nothing to do with it. Assigning the value of 512 happens when the app loads (really at build time), and only "happens" once. Because it's global, any value you set remains until you change it again.

If you want an instance variable that's tied to the class, declare it like this...

@implementation NKAddPostViewController
{
    int _characterCounter;
}

Note that you can't initialize variables with the declaration. Use your init override or viewDidLoad:.