I’m going to guess that nobody can predict which will be better, it depends on what you intend to do with this BUT… I’ll suggest that “none of the above” is the easiest, most straightforward way.
Aren’t these tiles already known as “spawn” them? In which case you create one, assign whatever values you will need to properties and place the tile reference in a collection of some type so you can access it as needed.
For any tile-based game such as Match3 or Tetris or a grid-based Roguelike, do all the logical comparisons in your own data storage mechanism for the tiles, such as a 2D array of tiles.
Otherwise you needlessly bind your game logic into Unity objects and the Unity API, making it about 10x more complicated than it needs to be.
If you have no idea how to work with 2D arrays, hurry to some basic C# tutorials for the language portions of it, then look at any good tutorial that uses a 2D array
Here is my Match3 demo using this technique of storing data in a grid. Full source linked in game comments.
It stores all of its data in a 2D array:
PieceController[,] Board;
This allows for easy simple checking in code, not relying on anything like physics.
You should strive to use that pattern for all logic, then only use Unity to present what is happening in the game logic.
Two steps to tutorials and / or example code:
do them perfectly, to the letter (zero typos, including punctuation and capitalization)
stop and understand each step to understand what is going on.
If you go past anything that you don’t understand, then you’re just mimicking what you saw without actually learning, essentially wasting your own time. It’s only two steps. Don’t skip either step.