我有2个班级AuthManager
,AuthView
。我想在实现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
内,__authView
(handle
)是!=无。但是,__authView
之后发布了loadAuthView
。
问题:为什么会这样?如何保持__authView
(handle
)不被释放?
而且,如果我在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];
}
任何帮助或建议将不胜感激。
谢谢。
答案 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;