Benefit of PaymentSplitter vs a push-style withdraw function?

I'm trying to weigh the pros and cons of using PaymentSplitter vs a commonly-used push-style withdraw function.

A push-style withdraw could be something like:

function withdraw() external payable onlyOwner {
    uint256 balance = address(this).balance;
    
    (bool successA, ) = addressA.call{value: balance / 100 * 17}("");
    require(successA, "Failed to send to A");

    (bool successB, ) = addressB.call{value: balance / 100 * 33}("");
    require(successB, "Failed to send to B");

    (bool successC, ) = addressC.call{value: balance / 100 * 50}("");
    require(successC, "Failed to send to C");
}

Side note, what does wrapping an address like payable(addressA).call do? Should I be doing that in the example above? In the example, the owner will be paying the gas right?

PaymentSplitter Pros:

  • is a pull-payment approach considered "safer"?
  • accounts can pull whenever they feel like by calling release
  • puller pays the gas fee rather than the contract owner?

PaymentSplitter Cons:

  • importing another contract
  • what if you have non-technical account users, how do you direct them to release their funds?

Can someone verify my pros and cons?

Also, what is the best practice in terms of calling your smart contract functions as the owner, after it has been deployed? For example, as the owner after the sale is done I want to call the withdraw function. Or maybe weeks later I want to call a function that just returns some value, what's the best way? Use hardhat console?