当前位置:K88软件开发文章中心编程语言Objective-CObjective-C01 → 文章内容

对象之间的通讯

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-10 11:12:24

t)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat retVal = 0;
if ([[UIViewControllerA class] instancesRespondToSelector:@selector(tableView:heightForRowAtIndexPath:)]) { retVal = [super tableView:self.tableView heightForRowAtIndexPath:indexPath];
{
return retVal + 10.0f;
{
就像上面的丑陋的代码,
一个委托方法也比重载方法好。
多重委托多重委托是一个非常基础的概念,
但是,
大多数开发者对此非常不熟悉而使用 NSNotifications。
就像你可能注意到的,
委托和数据源是对象之间的通讯模式,
但是只涉及两个对象:委托者和委托。
数据源模式强制一对一的关系,
发送者来像一个并且只是一个对象来请求信息。
但是委托模式不一样,
它可以完美得有多个委托来等待回调操作。
至少两个对象需要接收来自特定委托者的回调,
并且后一个需要知道所有的委托,
这个方法更好的适用于分布式系统并且更加广泛用于大多数软件的复杂信息流传递。
多重委托可以用很多方式实现,
读者当然喜欢找到一个好的个人实现,
一个非常灵巧的多重委托实现可以参考 Luca Bernardi 在他的 LBDelegateMatrioska 的原理。
一个基本的实现在下面给出。
Cocoa 在数据结构中使用弱引用来避免引用循环,
我们使用一个类来作为委托者持有委托对象的弱引用。
@interface ZOCWeakObject : NSObject@property (nonatomic, weak, readonly) id object;
+ (instancetype)weakObjectWithObject:(id)object;
- (instancetype)initWithObject:(id)object;
@end@interface ZOCWeakObject ()@property (nonatomic, weak) id object;
@end@implementation ZOCWeakObject+ (instancetype)weakObjectWithObject:(id)object { return [[[self class] alloc] initWithObject:object];
{
- (instancetype)initWithObject:(id)object { if ((self = [super init])) { _object = object;
{
return self;
{
- (BOOL)isEqual:(id)object { if (self == object) { return YES;
{
if (![object isKindOfClass:[object class]]) { return NO;
{
return [self isEqualToWeakObject:(ZOCWeakObject *)object];
{
- (BOOL)isEqualToWeakObject:(ZOCWeakObject *)object { if (!object) { return NO;
{
BOOL objectsMatch = [self.object isEqual:object.object];
return objectsMatch;
{
- (NSUInteger)hash { return [self.object hash];
{
@end一个简单的使用 weak 对象来完成多重引用的组成部分:@protocol ZOCServiceDelegate <
NSObject>
@optional- (void)generalService:(ZOCGeneralService *)service didRetrieveEntries:(NSArray *)entries;
@end@interface ZOCGeneralService : NSObject- (void)registerDelegate:(id<
ZOCServiceDelegate>
)delegate;
- (void)deregisterDelegate:(id<
ZOCServiceDelegate>
)delegate;
@end@interface ZOCGeneralService ()@property (nonatomic, strong) NSMutableSet *delegates;
@end@implementation ZOCGeneralService- (void)registerDelegate:(id<
ZOCServiceDelegate>
)delegate { if ([delegate conformsToProtocol:@protocol(ZOCServiceDelegate)]) { [self.delegates addObject:[[ZOCWeakObject alloc] initWithObject:delegate]];
{
{
- (void)deregisterDelegate:(id<
ZOCServiceDelegate>
)delegate { if ([delegate conformsToProtocol:@protocol(ZOCServiceDelegate)]) { [self.delegates removeObject:[[ZOCWeakObject alloc] initWithObject:delegate]];
{
{
- (void)_notifyDelegates { ... for (ZOCWeakObject *object in self.delegates) { if (object.object) { if ([object.object respondsToSelector:@selector(generalService:didRetrieveEntries:)]) { [object.object generalService:self didRetrieveEntries:entries];
{
{
{
{
@end在 registerDelegate: 和 deregisterDelegate: 方法的帮助下,
连接/解除组成部分很简单:如果委托对象不需要接收委托者的回调,
仅仅需要'
unsubscribe'
.这在一些不同的 view 等待同一个回调来更新界面展示的时候很有用:如果 view 只是暂时隐藏(但是仍然存在),
它可以仅仅需要取消对回调的订阅。

上一页  [1] [2] [3] [4] 


对象之间的通讯