ARC使用Objective-C在Xcode中无法正常工作

时间:2016-09-16 02:11:52

标签: objective-c xcode memory-management automatic-ref-counting

我对Xcode中使用Obj-C的强引用和弱引用感到困惑。 当我创建两个内部相互交叉引用的对象时,所有弱点:

 Mouse *mouse = [[Mouse alloc] initWithComputer:nil];
 Computer *computer = [[Computer alloc] initWithMouse:mouse];

 NSLog(@"%@", computer.mouse);  //prints legit address

 mouse = nil;  //destroy the ONLY strong reference to Mouse

 NSLog(@"%@", computer.mouse); //still prints(holds) the same legit address 

mouse = nil;

之前

enter image description here

mouse = nil;

之后

enter image description here

"摧毁"对于鼠标类鼠标的唯一强引用,鼠标 computer.mouse 的实例在应该释放时仍保留相同的内存地址。

只有Xcode中的SWIFT中的相同代码才能正常工作并释放 computer.mouse 所占用的内存,使其 nil

我的Obj-c代码有什么问题吗?我的Xcode是最新的,虽然在之前的版本中,我在Obj-c中也没有运气。我将不胜感激任何帮助。

以下是我的课程:

Computer.h

#import <Foundation/Foundation.h>
@class Mouse;

@interface Computer : NSObject

@property (nonatomic, weak) Mouse *mouse;

- (instancetype) initWithMouse: (Mouse *) userPutMouse ;

@end

Computer.m

#import "Computer.h"
#import "Mouse.h"

@implementation Computer

- (instancetype) initWithMouse: (Mouse *) userPutMouse {

    self = [super init];

    if (self) {

        self.mouse = userPutMouse;
        self.mouse.computer = self;

    }

    return self;
}

@end

Mouse.h

#import <Foundation/Foundation.h>
@class Computer;

@interface Mouse : NSObject 

@property (nonatomic, weak) Computer *computer;

- (instancetype) initWithComputer: (Computer *) userPutComputer;

@end

Mouse.m

#import "Mouse.h"
#import "Computer.h"

@implementation Mouse

- (instancetype) initWithComputer: (Computer *) userPutComputer {

    self = [super init];

    if (self ) {

        if (userPutComputer) {
            self.computer = userPutComputer;
        }

    }

    return self;
}

@end

1 个答案:

答案 0 :(得分:4)

自动合成的getter将他们返回的对象放入自动释放池中。因此,您将mouse分配给nil并不会终止最终的拥有参考。永远不要假设您是唯一拥有任何引用的人,只能确保您遵循适当的行为。

对于经验证明,试试这个:

Mouse *mouse;
Computer *computer;

@autoreleasepool {

    mouse = [[Mouse alloc] initWithComputer:nil];
    computer = [[Computer alloc] initWithMouse:mouse];

    NSLog(@"%@", computer.mouse);  //prints legit address

    mouse = nil;  //destroy **my** ONLY strong reference to Mouse

}

NSLog(@"%@", computer.mouse); //prints (null)

......但也绝不会试图通过经验来诊断正确的所有权。这就是为什么retainCount属性不再可用的原因。

编辑:扩展:getter的传统行为是返回一个非拥有引用,但仍保证至少与当前调用堆栈一样长。这样,在ARC之前的日子里,您可以直接使用getter来提供属性作为参数(在这种情况下,不会给调用者带来内存管理负担)或者获取调用者可以暂时保留的内容,即使原始所有者在此期间被解除分配(即经典自动释放池使用的东西有点像他们只是在堆栈上)。然后ARC只是实现了老式的规则,但是自动实现了完全的互操作性。