Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using __weak to modify storage of a parameter in implementation

Is it valid to use the __weak storage modifier in a method's implementation's signature? Especially if it is not part of the method's public signature? For example:

- (UIView *)tableView:(__weak UITableView *)tableView viewForHeaderInSection:(NSInteger)sectionIndex
{
    UIView *view = [ABHeaderView view];
    view.actionBlock = ^{
        [tableView doSomething];
    }
    // ...
    return view;
}

Does this correctly use tableView as a weak pointer? Or should I really do something like __weak *weakTableView = tableView; and use weakTableView within the block?

I do not get any warnings or errors and the clang Static Analyzer does not throw any warnings.

like image 873
hypercrypt Avatar asked Apr 17 '12 08:04

hypercrypt


Video Answer


1 Answers

Don't count on storage modifiers or attributes to be honored 'dynamically' when dynamic dispatch is involved and overriding(1).

This method is formally declared in UIKit. The compiler may get it wrong when using ARC because it may match the selector to the original declaration when called. That is, your declaration is not visible to UIKit, and UIKit will treat it as default/strong if it's compiled as ARC as well. This could happen if the declarations do not match, or even if they are not visible in the client+caller translation.

Parameter types/attributes are not part of the selector, nor are they applied to dispatch dynamically. ARC should assume strong here, and that the caller holds the reference. This specific example may not cause a runtime error, but it's a questionable practice which I assume errors could be found. I've proven this for attributes in this answer. Fundamentally, it is a similar concept.

Simple rule with dynamic objc dispatch: Always match the signature of the original declaration when redeclaring, defining, and overriding. The only exception one might make is for C compatible qualifiers which would not alter the signature (a very uncommon practice in ObjC programs I've seen).

(1) technically, it's not an override, but an implementation of the protocol's method. regardless, the sig should be identical.

like image 174
justin Avatar answered Nov 15 '22 05:11

justin