ComponentKit/Core/Action/CKComponentDelegateAttribute.mm (45 lines of code) (raw):
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "CKComponentDelegateAttribute.h"
#import <vector>
#import <objc/runtime.h>
#import <RenderCore/RCAssert.h>
#import "CKComponent+UIView.h"
#import "CKComponentSubclass.h"
CKComponentViewAttributeValue CKComponentDelegateAttribute(SEL selector,
CKComponentForwardedSelectors selectors) noexcept
{
if (selector == NULL) {
return {
{
std::string("Delegate-noop-") + sel_getName(selector) + "-",
^(UIView *view, id value) {}, ^(UIView *view, id value) {}
},
@YES // Bogus value, we don't use it.
};
}
return {
{
std::string(sel_getName(selector)) + CKIdentifierFromDelegateForwarderSelectors(selectors),
^(UIView *view, id value){
// Create a proxy for this set of selectors
RCCAssertNil(CKDelegateProxyForObject(view),
@"Unsupported: registered two delegate proxies for the same view: %@ %@", view, CKDelegateProxyForObject(view));
CKComponentDelegateForwarder *proxy = [CKComponentDelegateForwarder newWithSelectors:selectors];
proxy.view = view;
CKSetDelegateProxyForObject(view, proxy);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[view performSelector:selector withObject:proxy];
#pragma clang diagnostic pop
},
^(UIView *view, id value){
// When unapplied, remove association with the view
CKComponentDelegateForwarder *proxy = CKDelegateProxyForObject(view);
proxy.view = nil;
CKSetDelegateProxyForObject(view, nil);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[view performSelector:selector withObject:nil];
#pragma clang diagnostic pop
}
},
@YES // Bogus value, we don't use it.
};
}