How safe is it to use a class pointer?

How safe is using a class with Objective-C?

-> I can store the class safe in the dictionary and compare

info[@"class"] = [User class]; ... if ([User class] == info[@"class"]) { } 

-> can a class pointer change?

-> Nil will never be in quarantine?

+5
source share
2 answers

Class objects behave like regular objects. They can be stored, released, passed as arguments and return values, stored in ivars and properties, stored in containers - basically anything.

[SomeClassName class] usually not compiled or linked if such a class cannot be found, but it can be compiled, but return zero, for example, when working in an OS that does not have this class, ie An older OS version than the development SDK version. The return value of NSClassFromString will be nil if such a class does not exist.

The value of the pointer (identifier) ​​of class objects never changes. There is only one class object for each class name, and you can use the C == operator to check if the class pointers are the same. (The subclass / superclass relation can be checked using the class method + isSubclassOfClass: .

Class objects are never freed - you can rely on them to be alive (i.e. without saving them) until the process completes completely.

The above is true for most applications; however, there is a complex case of beam loading (and an even more complicated case of beam unloading):

  • A boot package can add classes at runtime, for example. calling NSClassFromString to start returning non-nil for its names.
  • If dynamic package loading causes class name collisions, the runtime currently logs a complaint but continues to work; it is not indicated what exactly happens in this case.
  • With Mac OS X 10.5, you can download a package that causes its classes to be deleted. It is not indicated what should happen if some of these classes were saved.
+4
source

Of course [User class] may be Nil .
+ class is a static method defined in the NSObject class, so this means that everyone can override + class and return any value.

Here is an example of how [User class] can return Nil

 @implementation User + (Class)class { return Nil; } @end 

Also [User class] can return any value, and the pointer can be changed

 @implementation User + (Class)class { switch (arc4random() % 3) { case 0: return [UIButton class]; break; case 1: return [UILabel class]; break; case 2: return [NSString class]; break; default: break; } return Nil; } @end 

The apple provided to the classes will always work as expected (for example, @hamstergene suggests), BUT ONLY if their +class method is not checked by the programmer.

Therefore, using [User class] not a safe way.
Instead, get classes directly from the runtime using the runtime function

 #import <objc/runtime.h> info[@"class"] = objc_getClass("User") 
+2
source

Source: https://habr.com/ru/post/1207223/


All Articles