Why use typeof () instead of an object type, avoiding block saving cycles?

I often saw this piece of code when another ObjC developer breaks the save loop.

__weak typeof(self) weakSelf = self;
[someObject doThingWithCompletion:^{
    typeof(weakSelf) strongSelf = weakSelf;
    [strongSelf awesomeThingOne];
    [strongSelf moreAwesome];
}];

Why use a macro typeof()? Is it unique to blocks?

My initial thought is that the type selfmay not be known (which seems mostly impossible, but let it pretend ...). If the type is unknown, why not declare weakSelfusing id: __weak id weakSelf = self;?

My second thought is that it protects against subclassification, but this is unlikely to cause a problem. Suppose ObjTwosubclasses AwesomeObjand override the method awesomeThingOne. The fake code above should work fine if it selfis an instance of ObjTwoor AwesomeObj.

+4
source share
1 answer

A macro typeof()allows several things.

First of all, personally, I created a code snippet with such things. Instead of typing:

__weak MyClass *weakSelf = self;

every time I want to set this, substituting MyClassfor the corresponding class, I can instead just start typing weakSelf, and Xcode autocomplete will try to offer my this line of code:

__weak typeof(self) weakSelf = self;

This will work every time.


In addition, use typeof()gives us an explicit type and minimizes the code for rewriting if we ever change the actual type.

idit is unsafe and it will not give us autocomplete of available methods and properties. In the end, it weakSelfnow has a type id, not a type MyClass.

, , MyClass, :

weak MyClass *weakSelf = self;

/, MySubClass, self MySubClass.


typeof() . typeof() .

, :

+ (instancetype)myInstance {
    return [[self alloc] init];
}

instancetype [self alloc] , .

, - :

+ (NSMutableArray *)arrayOfInstances;

, , , ?

+ (NSMutableArray *)arrayOfInstances {
    NSMutableArray *instances = [NSMutableArray array];

    for (int i = 0; i < 10; ++i) {
        typeof([self alloc]) newObj = [[self alloc] init];
        newObj.someIntProperty = i;
        [instances addObject:newObj];
    }

    return instances;
}

id newObj. , :

[MyClass arrayOfInstances];

MyClass, :

[MySubClass arrayOfInstances];

MySubClass ..


typeof(), , :

Class dynamicType = myDict[@"Class"];
typeof([dynamicType alloc]) myObject = [[dynamicType alloc] init];
myObject.foo = myDict[@"Foo"];
myObject.bar = myDict[@"Bar"];
+7

All Articles