search

Home  >  Q&A  >  body text

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 days ago403

reply all(2)I'll reply

  • 天蓬老师

    天蓬老师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);
    }

    Specific questions, read this carefully
    http://clang.llvm.org/docs/AutomaticReferenceCounting.html
    You will understand everything after reading this. Memory management is just about this

    reply
    0
  • 巴扎黑

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

    When there is no pointer pointing to the memory space, it is automatically released.

     p.favor = arr;
     arr = nil;
    

    arr is a strong reference and has been set to nil. Naturally, p.favor cannot find the corresponding memory address, so it outputs (null).

    reply
    0
  • Cancelreply