2015-09-15 54 views
0

我有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)is!= nil。但是__authViewloadAuthView之外後被釋放。

問題:爲什麼會發生?並且如何保持__authViewhandle)不被釋放?

還有更多,如果我加載在AuthManager筆尖,它工作正常。

- (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]; 
} 

任何幫助或建議將不勝感激。

謝謝。

回答

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; 
+0

謝謝。我瞭解'void add(int b)'。但我通過'_authView'是一個指針。並且'handle = [[sdkBundle loadNibNamed ...'會使'__authView'改變? – anhtu

+0

您需要使用雙指針來修改指針。我已經更新了我的答案以包含一個例子。 –

+0

我試過'[AuthView loadAuthView:&__ authView];'並且得到錯誤**將非本地對象的地址傳遞給__autoreleasing參數用於回寫** – anhtu