In simple words we can say that @dynamic keyword tells the compiler that you will provide accessor methods dynamically at runtime. This can be done using the Objective-C runtime functions.
@dynamic just tells the compiler that the getter and setter methods are implemented not by the class itself but somewhere else like the superclass or will be provided at runtime.
@dynamic keyword is simply a hint to the compiler that it should not raise any warnings if no implementation for the property getter and setter is provided.
So if you want to declare and use properties, but want to avoid warnings about methods missing at compile time, you can use the @dynamic directive instead of @synthesize.
How @dynamic Works
When you invoke a method on an object, the runtime maps the selector of that method onto a concrete implementation and then executes the implementation. Typically, there are no getters or setters provided for a @dynamic property so the runtime calls resolveInstanceMethod: on your class instead. This method can examine the selector and provide a mapping to a C-style function using class_addMethod().
You return YES from resolveInstanceMethod: to indicate that you’ve resolved the method; otherwise the runtime will end up throwing an unrecognized selector exception. The runtime will also call resolveInstanceMethod: if you call respondsToSelector: or instancesRespondToSelector: is invoked.