Destroy and DestroyImmediate?

public void DeleteEveryCell()
    {
        Debug.Log("This cell num is " + thisCells.Count);
        foreach (StackCell cell in GetComponentsInChildren<StackCell>())
        {
            Destroy(cell.gameObject);
        }
        thisCells.Clear();
        Debug.Log("2 This cell num is " + thisCells.Count);
    }

// After instantiate 2 ui prefab for this cell, 

    public void SetCell()
    {
        thisCells = GetComponentsInChildren<StackCell>().ToList();
        Debug.Log("3 This cell num is " + thisCells.Count);
        ThisCellNum = thisCells.Count;
        SetCellMaxStackInit();
    }

So this does not operate well like, after destroy and clear, instantiate 2 objects, then at this line "Debug.Log(“3 This cell num is " + thisCells.Count);”,

result should be 2.

But console says it is 6. malfunction.

But after I change Destroy to DestroyImmediate, it works well like I anticipated.

But at Visual Studio’s intellisense, it says not use DestroyImmediate strongly.
Why?

Like it says on the reference page, it can permanently delete assets from your project.

https://docs.unity3d.com/ScriptReference/Object.DestroyImmediate.html

Why not? Its just UI prefab instantiated instance. Inside LayoutGroup of unity UI component.

Destroy queues gameobjects to be destroyed when application has time to do so.
E.g. on the start of the next frame.

Until that point - it is only marked as “destroyed / null” but not actually removed from anywhere.

DestroyImmediate destroys object on the same call, but that operation is very costly.
And, if used incorrectly - e.g. if prefab instead of prefab instance get passed - it will erase the prefab instead of prefab instance.

It can be used, just not advised to do so.

Also, note that you can pass lists directly to the GetComponentsInChildren;
E.g.

private List<SomeItem> _buffer = new List<SomeList>();

// To ensure there's no entries from previous calls
_buffer.Clear();

// Then call it like so:
GetComponentsInChildren(_buffer);

// Or set to true to fetch disabled objects' components as well
GetComponentsInChildren(true, _buffer);

This way you’ll avoid allocating array (via GetComponentsInChildren call) and allocating of list (via .ToList());

The best way to approach your problem is to avoid GetComponentsInChildren call.
Simply have a one hashset or list for the items to add / remove from upon adding / removing cells. If you’re using Instantiate, you can fetch component from the newly created instance and add it to the collection. Same goes for OnDestroy → remove the reference from internal collection.

TL;DR: Track objects manually without relying upon GetComponentsInChildren.

Thanks. I revised like,

group.DeleteEveryCell();
        for (int i = 0; i < many; i++)
        {
            GameObject newObj = Instantiate(CellPrefab) as GameObject;
            newObj.transform.SetParent(group.GetComponentInChildren<GridLayoutGroup>().transform);
            group.thisCells.Add(newObj.GetComponent<StackCell>());
        }
        group.SetCell();

Add cell right after instantiated to thisCells, then it can be used with just Destroy function.

But GetComponentsInChildren is so convenient to track.
How about using just at game start to store at some List variable?
But yes so should find way not using this as possible specially at runtime?
Even it is not calling every frame?