Как уже говорили другие, вы обычно используете @synthesize, чтобы компилятор генерировал для вас геттеры и / или настройки, и @dynamic, если вы собираетесь их писать самостоятельно.
Есть еще одна тонкость, еще не упомянутая: @synthesize будет позволять вам предоставлять реализацию самостоятельно, либо с использованием метода получения, либо установки. Это полезно, если вы хотите реализовать метод получения только для некоторой дополнительной логики, но позволить компилятору сгенерировать метод установки (который для объектов обычно немного сложнее написать самостоятельно).
Однако, если вы пишете реализацию для метода доступа @ synthesize, он все равно должен быть поддержан реальным полем (например, если вы пишете -(int) getFoo();
, у вас должно быть поле int foo;
). Если значение создается чем-то другим (например, вычисляется из других полей), тогда вы должны использовать @ dynamic.