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

ARC doesn't work properly in Xcode with Objective-C

我在使用 Obj-C 的 Xcode 中遇到了强引用和弱引用的两难选择。 当我创建两个内部相互交叉引用的对象时,所有对象都是弱的:

 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之前;

mouse = nil之后;

在 "destroying" 对 Mouse class mouse 的唯一强引用之后,Mouse computer.mouse[= 的一个实例51=] 在应该被释放时仍然持有相同的内存地址。

只有 SWIFT 和 Xcode 中的完全相同的代码才能正常工作并释放 computer.mouse 持有的内存,使其成为

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

这是我的 classes:

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

您的 getter 正在自动合成,正在将它们 return 的对象放入自动释放池中。因此,您将 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 的传统行为预期是 return 非拥有引用,但保证至少与当前调用堆栈一样长。这样一来,在 ARC 之前的日子里,您可以直接使用 getters 来提供属性作为参数(在这种情况下,不要让调用者承担内存管理的负担)或获得调用者可以保留的东西短暂地,即使原来的所有者同时被释放(即经典的自动释放池使用,使事情表现得有点像它们只是在堆栈上)。然后 ARC 只是自动执行老式规则,以实现完全互操作性。