搜尋

首頁  >  問答  >  主體

objective-c - xcode中啟用了arc後,是何時釋放物件?

剛學objective c,遇到記憶體管理問題,情景是這樣的:
啟用了arc,設定了一個Person類,只有一個weak的property,(NSMutableArray *)favor

Person.h如下

#import <Foundation/Foundation.h>

@interface Person : NSObject

@property (nonatomic, weak) NSMutableArray *favor;

@end

Person.m如下

#import "Person.h"

@implementation Person

- (void)dealloc {
    NSLog(@"Person dealloc!");
}
@end

main.m如下

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, char * argv[]) {
    Person *p = [[Person alloc] init];
    NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", nil];
    p.favor = arr;
    NSLog(@"%@", p.favor);
    arr = nil;
    NSLog(@"%@", p.favor);
}

控制台印製的結果是這樣的

2015-09-11 13:31:14.408 Prog1[32787:193921] (
    1,
    2
)
2015-09-11 13:31:14.409 Prog1[32787:193921] (
    1,
    2
)
2015-09-11 13:31:14.409 Prog1[32787:193921] Person dealloc!

我的分析是:arr剛開始指向的物件只有arr一個強指標指向它,雖然p.favor = arr,但favor屬性是weak的,那麼當arr = nil時,這個物件就沒有強指標指向它了,此時該物件應該被釋放,但是第二次列印的結果表明並沒有被釋放
再但是,當我註解掉第一次的列印,即

#import <Foundation/Foundation.h>
#import "Person.h"

int main(int argc, char * argv[]) {
    Person *p = [[Person alloc] init];
    NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", nil];
    p.favor = arr;
//    NSLog(@"%@", p.favor);
    arr = nil;
    NSLog(@"%@", p.favor);
}

印結果卻是

2015-09-11 13:44:48.956 Prog1[36117:210004] (null)
2015-09-11 13:44:48.958 Prog1[36117:210004] Person dealloc!

即表示對像被釋放了

我的問題是:

  1. 啟用了arc後,物件在沒有強指標(強引用)的情況下是否被立即釋放?如果不是,是什麼時候釋放? (注意我用init開頭的方法建立的陣列對象,在非arc情況下是不會autorelease的,main函數中我也沒有@autoreleasepool)

  2. 點語法是否會影響物件釋放? (我提這個問題的原因是,當我不用property而是把favor設為@public的成員變數時,用p->_favor列印第一次就不會出現arr = nil後沒有被釋放的情況)

  3. arc到底是怎樣決定何時釋放對象的呀?我知道arc是編譯時就決定了何時release retain autorelease,那它是怎麼決定的呢?

迷茫迷茫2766 天前397

全部回覆(2)我來回復

  • 天蓬老师

    天蓬老师2017-04-24 16:02:24

    #import <Foundation/Foundation.h>
    #import "Person.h"
    
    int main(int argc, char * argv[]) {
        // 这里的p是什么引用 默认必须是强引用 ARC会在当前函数栈 结束时 做RetainCount-1
        Person *p = [[Person alloc] init];
        // 同理的arr是强引用 所以 后面的代码 同样不会有问题 跟你weak不weak没关系
        NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", nil];
        p.favor = arr;
        NSLog(@"%@", p.favor);
        arr = nil;
        NSLog(@"%@", p.favor);
    }

    具體的問題 好好讀讀這個
    http://clang.llvm.org/docs/AutomaticReferenceCounting.html
    讀完你就​​全明白了 記憶體管理就這點事兒

    回覆
    0
  • 巴扎黑

    巴扎黑2017-04-24 16:02:24

    當該記憶體空間沒有指標指向它了,它就被自動釋放了。

     p.favor = arr;
     arr = nil;
    

    arr是強引用,已經被置nil了,p.favor自然也就找不到對應記憶體位址了,所以輸出(null)。

    回覆
    0
  • 取消回覆