2009-06-04 2 views
13

Я читал RAII и отдельно от двухфазной конструкции/инициализации. По какой-то причине я был в двухэтапном лагере до недавнего времени, потому что в какой-то момент я, должно быть, слышал, что плохо делать операции с ошибками в вашем конструкторе. Однако я думаю, что теперь я убежден, что однофазный предпочтительнее, основываясь на вопросах, которые я прочитал о SO и других статьях.Объектив C двухфазное построение объектов

Мой вопрос: Почему Objective C использует двухфазный подход (alloc/init) почти исключительно для конструкторов без удобства? Есть ли какая-то конкретная причина в языке, или это просто дизайнерское решение дизайнеров?

ответ

28

У меня есть завидная ситуация для парня, который написал +alloc еще в 1991 году, и мне довелось задать ему очень похожий вопрос несколько месяцев назад. Добавление +alloc состояло в том, чтобы предоставить +allocWithZone:, что было сделано для добавления пулов памяти в NeXTSTEP 2.0, где память была очень плотной (4M). Это позволило вызывающему абоненту управлять тем, где объекты были выделены в памяти. Это была замена на +new и его род, который был (и продолжает оставаться, хотя никто его не использует), 1-фазный конструктор, основанный на Smalltalk new. Когда Cocoa пришла в Apple, использование +alloc было уже укоренилось, и не было возврата к +new, хотя фактически выбор вашего NSZone редко имеет значительную ценность.

Так что это не большой 1-фазный/2-фазный философский вопрос. На практике Cocoa имеет однофазную конструкцию, потому что вы всегда (и всегда должны) вызывать их поочередно в один звонок без теста на +alloc. Вы можете думать об этом как о сложном способе ввода «нового».

+3

+1 Вау, я не мог бы попросить лучшего ответа –

3

Мой опыт работы с C++, но один недостаток однофазной инициализации C++ - обработка наследования/виртуальных функций. В C++, you can't call virtual functions during construction or destruction (ну, вы можете, он просто не будет делать то, что вы ожидаете). Двухэтапный init мог бы решить эту проблему (частично. Из того, что я понимаю, он будет перенаправлен в нужный класс, но init, возможно, еще не закончил. Вы все еще можете с этим поделать) (я все еще поддерживаю одна фаза)

Смежные вопросы