变量总是按值传递

时间:2015-09-15 03:56:46

标签: ios objective-c

我有2个班级AuthManagerAuthView。我想在实现AuthView文件(.m)中加载AuthView的nib文件。 我在AuthView中创建了一个静态方法:

+ (void)loadAuthView:(AuthView *)handle
{
  NSBundle * sdkBundle = [NSBundle bundleWithURL:
                          [[NSBundle mainBundle]
                           URLForResource:SDK_BUNDLE_NAME withExtension:@"bundle"]];
  // handle == nil
  handle = [[sdkBundle loadNibNamed:AUTHVIEW_NIB_NAME owner:nil options:nil] firstObject];
  // handle != nil
}

AuthManager,我有一个属性:

@property (nonatomic, strong) AuthView * _authView;

一种方法:

- (void)showAuthViewInView:(UIView *)view
{
  if (__authView == nil) {
    [AuthView loadAuthView:__authView];
    // __authView ( handle ) == nil ??????????????
  }

  [__authView showInView:view];
}

问题:在loadAuthView内,__authViewhandle)是!=无。但是,__authView之后发布了loadAuthView

问题:为什么会这样?如何保持__authViewhandle)不被释放?

而且,如果我在AuthManager中加载nib,它可以正常工作。

- (void)showAuthViewInView:(UIView *)view
{
  if (__authView == nil) {
    NSBundle * sdkBundle = [NSBundle bundleWithURL:
                            [[NSBundle mainBundle]
                             URLForResource:SDK_BUNDLE_NAME withExtension:@"bundle"]];
    __authView = [[sdkBundle loadNibNamed:AUTHVIEW_NIB_NAME owner:nil options:nil] firstObject];
  }

  [__authView showInView:view];
}

任何帮助或建议将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:2)

您必须返回句柄,以便ARC知道该对象仍被引用。

loadAuthView:更改为

+ (AuthView *)loadAuthView
{
  NSBundle * sdkBundle = [NSBundle bundleWithURL:
                          [[NSBundle mainBundle]
                           URLForResource:SDK_BUNDLE_NAME withExtension:@"bundle"]];
  // handle == nil
  AuthView *handle = [[sdkBundle loadNibNamed:AUTHVIEW_NIB_NAME owner:nil options:nil] firstObject];
  // handle != nil
  return handle;
}

- (void)showAuthViewInView:(UIView *)view
{
  if (__authView == nil) {
    __authView = [AuthView loadAuthView];
  }

  [__authView showInView:view];
}

您很困惑,变量总是按值传递(不是参考)。在原始代码中,修改handle中的loadAuthView修改__authView的值,因为handle__authView的新副本}。修改__authView的唯一方法是使用=运算符直接分配它(让我们忽略指向指针的指针)。

这是一个简单的例子:

void add(int b) {
  // b is 1
  b = b + 1;
  // b is 2
} // the value of b is discarded
int a = 1; // a is 1
add(a);
// a is still 1

void add2(int b) {
  return b + 1;
}
a = add2(a);
// a is 2 now

修复原始方法的另一种方法(不推荐)是使用双指针(AuthView **

+ (void)loadAuthView:(AuthView **)handle
{
  NSBundle * sdkBundle = [NSBundle bundleWithURL:
                          [[NSBundle mainBundle]
                           URLForResource:SDK_BUNDLE_NAME withExtension:@"bundle"]];
  *handle = [[sdkBundle loadNibNamed:AUTHVIEW_NIB_NAME owner:nil options:nil] firstObject];
}

AuthView *authView; // make a local variable to avoid ARC issue
[AuthView loadAuthView:&authView];
__authView = authView;