在 Objective-C 中销毁一个对象

Mic*_*ton 3 objective-c ios

我正在尝试实现一个链表,所以我有一个带有头文件的 Node 类,如下所示:

@interface Node : NSObject

@property(nonatomic,assign)int data;
@property(nonatomic,strong) Node *right;
@property(nonatomic,strong) Node *left;

@end
Run Code Online (Sandbox Code Playgroud)

然后在另一个类中,我分配它们,然后调用一个方法来销毁给定值的所有出现:

Node *node0 = [[Node alloc]init];
Node *node1 = [[Node alloc]init];
Node *node2 = [[Node alloc]init];
Node *node3 = [[Node alloc]init];
Node *node4 = [[Node alloc]init];
node0.data = 1;
node1.data = 2;
node2.data = 5;
node3.data = 5;
node4.data = 3;
node0.right = node1;
node1.right = node2;
node2.right = node3;
node3.right = node4;
node4.right = NULL;
[self removeNodeWithValue:node0 value:5];
NSLog(@"node %d, %d, %d, %d, %d", node0.data, node1.data, node2.data, node3.data, node4.data);
Run Code Online (Sandbox Code Playgroud)

这是方法本身:

-(void)removeNodeWithValue:(Node *)head value:(int)value
 {
  Node *toDelete;
  while (head != NULL) {
    if (head.data == value)
    {
        toDelete = head;
        head = head.right;
        toDelete = nil;
    }
    else
    {
       head = head.right;
    }
  }
 }
 ==> 1, 2, 5, 5, 3
Run Code Online (Sandbox Code Playgroud)

我知道我可以更改实例,因为如果我更改toDelete = niltoDelete.data = 4,则输出为==> 1, 2, 4, 4, 3。我的问题是,如何销毁这些实例?谢谢。

Ram*_*uri 5

看来你还没有理解ARC是如何工作的。只要存在指向该对象的强指针,该对象就不会被释放。在您的示例中,您的代码因两个原因而失败:首先,您始终保持对以下内容的强引用node0

Node *node0 = [[Node alloc]init];
Run Code Online (Sandbox Code Playgroud)

只要该指针未设置为nil(请记住,按照惯例,NULL用于常规指针、nil对象指针),该节点就不会被释放。

其次,如果要释放的节点不是第一个节点,则有另一个节点持有指向它的强指针,这就是该节点不会被释放的另一个原因。保留另一个指向node0toDelete在您的情况下)的指针将增加该节点的节点保留计数,并且当您将其设置为nil它时,它将返回到其原始值。

为了正确地做到这一点,您还必须避免链删除(如果第一个节点被释放,它将失去对第二个节点的强引用,如果没有指向它的强指针,第二个节点可能会被释放,并且也会导致第三个节点被释放,等等)。

最后,我建议不要只保存一堆指向每个节点的指针,而是实现一个链表类,它将完成添加/删除节点的工作:

@interface List : NSObject

@property (nonatomic, strong) Node* first;
@property (nonatomic, weak) Node* last;

@end

// Inside the class implementation

- (void) addNodeWithValue: (int) value
{
    Node* node= [[Node alloc]init];
    node.data= value;
    if(!first)
    {
        last= first= node;
    }
    else
    {
        last.right= node;
        node.left= last;   // left should be a weak property
        last= node;
    }
}

- (void) removeNodeWithValue: (int) value  // O(n) method
{
    Node* ptr= first;
    while(ptr) 
    {
        if(ptr.data== value)
        {
            if(ptr== first)
            {
                first= last= nil;
            }
            else
            {
                ptr.left.right= ptr.right;
                ptr.right.left= ptr.left;
            }
            break;  // Remove the break if you want to remove all nodes with that value
        }
        ptr= ptr.right;
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有测试过这段代码,我不能保证它有效。