This behaviour is due to the NS_CLASS_AVAILABLE macro. This macro has been implemented on most (all?) UIKit classes, and will return nil for a class that is not available. This allows you to check for the existence of a class on a specific iOS version with the code:
if ([UICollectionView class]) {
// class exists, must be iOS6+
}
Now, your call to [[UICollectionView alloc] init]
is a class method call on a nil class, which will always return nil.
To answer your secondary question, the correct way of checking for class existence is to check if the class is nil or not, as above. NSStringFromClass is not needed any more.
So, on to question 3. I was also surprised by this one, but it appears that protocol objects are compiled directly into the binary. As you are compiling using the latest SDK, the code compiles fine and the protocol will be available when running on an SDK version that has not introduced the protocol yet, as no linking to the missing class is required. This means the Protocol
object will be valid, and the class will correctly respond to conformsToProtocol:
with no problems, no matter what iOS version you are running. This can be easily seen using otool -l
on a compiled binary, which will show the protocols conformed to by a class and their methods. The protocols themselves seem to live in a section called __objc_protolist
. Output for a class conforming to UICollectionViewDelegate and DataSource is shown below:
000050a4 0x5cf4
isa 0x5d08
superclass 0x0
cache 0x0
vtable 0x0
data 0x5b30 (struct class_ro_t *)
flags 0x80
instanceStart 156
instanceSize 156
ivarLayout 0x0
name 0x4a0f TTViewController
baseMethods 0x5b10 (struct method_list_t *)
entsize 12
count 2
name 0x3eb8 viewDidLoad
types 0x4955 v8@0:4
imp 0x2620
name 0x3ec4 didReceiveMemoryWarning
types 0x4955 v8@0:4
imp 0x2670
baseProtocols 0x5ad8
count 2
list[0] 0x5da0 (struct protocol_t *)
isa 0x0
name 0x4997 UICollectionViewDelegate
protocols 0x5304
instanceMethods 0x0 (struct method_list_t *)
classMethods 0x0 (struct method_list_t *)
optionalInstanceMethods 0x5310
optionalClassMethods 0x0
instanceProperties 0x0
list[1] 0x5dcc (struct protocol_t *)
isa 0x0
name 0x49ce UICollectionViewDataSource
protocols 0x53d8
instanceMethods 0x53e4 (struct method_list_t *)
entsize 12
count 2
name 0x394e collectionView:numberOfItemsInSection:
types 0x455d i16@0:4@8i12
imp 0x0
name 0x3975 collectionView:cellForItemAtIndexPath:
types 0x4589 @16@0:4@8@12
imp 0x0
classMethods 0x0 (struct method_list_t *)
optionalInstanceMethods 0x5404
optionalClassMethods 0x0
instanceProperties 0x0
ivars 0x0
weakIvarLayout 0x0
baseProperties 0x0