Я думаю, что NSNumber имеет специальную реализацию, как и NSString.
[NSNumber alloc] фактически не выделяет память, а возвращает общий указатель. Распределение будет обрабатываться одним из методов init, но здесь снова initWithInt: 5 - такая распространенная ситуация, что вместо создания нового объекта возвращается указатель на значение по умолчанию. И этого нельзя все равно выпустить.
// do it once
NSNumber* five1 = [NSNumber alloc];
NSLog(@"%p", five1);
five1 = [five1 initWithInt:5];
NSLog(@"%p", five1);
// and once more
NSNumber* five2 = [NSNumber alloc];
NSLog(@"%p", five2);
five2 = [five2 initWithInt:5];
NSLog(@"%p", five2);
В самом деле, не должно быть никаких проблем с отправкой сообщение об освобождении более чем один раз:
[five1 release];
[five1 release];
[five1 release];
Чисто предположение, как я не разработчик Objective-C, но я бы сказал, что объект, на который указывает, может быть освобожден, но упомянутая ячейка памяти все еще содержит значение 5. –