when you are using the self.users, you access the property via the setter or getter.
when you are using the _users, you access the property directly skip the setter or getter.
here is a good demonstration of it:
- (void)setUsers:(id)users {
self.users = users; // WRONG : it causes infinite loop (and crash), because inside the setter you are trying to reach the property via setter
}
and
- (void)setUsers:(id)users {
_users = users; // GOOD : set your property correctly
}
this is the point in the case of the getter as well.
about the basic memory management (in case of MRR or ARC): the iOS will dealloc the object if there is no more strong pointer which keeps it alive, no matter how you release the pointer of the objects.