【问题标题】:Extending existing Object (ISA Swizzling?)扩展现有对象(ISA Swizzling?)
【发布时间】:2018-05-28 17:08:39
【问题描述】:

以下问题:我从框架(不可实例化)收到一个对象,我想扩展它。当我创建一个类别时,问题是它对现有对象没有影响。

我想到了 isa swizzling。所以让 isa 字段指向扩展的“选择器列表”。但这似乎不可能? (它的语法?)

有人知道更好的方法吗?

那是代码:

- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray<CBATTRequest *> *)requests {
      //want to do something that uses the extension
}

我想扩展 CBATTRequest。我认为问题在于CoreBluetooth?

这就是我创建类别的方式:

BLERequestable.h

@protocol BLERequestable <NSObject>

- (nonnull NSString *)getCentralUUID;
- (nonnull NSString *)getCharacteristicUUID;
- (nullable NSData*)getData;
- (void)setData:(nullable NSData *) data;

@end

CBATTRequest+Requestable.h

#import <CoreBluetooth/CoreBluetooth.h>
#import "BLERequestable.h"

@interface CBATTRequest (Requestable) <BLERequestable>

@end

CBATTRequest+Requestable.m

#import "CBATTRequest+Requestable.h"

@implementation CBATTRequest (Requestable)

 - (NSString *)getCentralUUID {
    return self.central.identifier.UUIDString;
}

- (NSString *)getCharacteristicUUID {
    return self.characteristic.UUID.UUIDString;
}

- (NSData*)getData {
    return self.value;
}

- (void)setData:(NSData *) data {
    self.value = data;
}


@end

然后我将类别导入任何我想使用的地方。

【问题讨论】:

  • 当您说“扩展它”时,您的意思是“向其中添加方法”还是“改变现有方法的功能”?前者是类别所做的,并且绝对应该可以工作(如果您遇到问题,请显示代码和错误)。后者可以通过 swizzling 来完成,但非常危险,在很多情况下它不起作用,在一些情况下它似乎可以工作,但会巧妙地破坏事物,以及它在一个版本的操作系统中工作并中断的情况在以后的版本中。在生产代码中应强烈避免。
  • 我想给它添加方法。你是对的,@RobNapier。通常它应该与扩展一起使用。但在这种情况下它没有。我用一些代码编辑了我的帖子。
  • 如何将类别添加到CBATTRequest?它应该是 @interface CBATTRequest (MyExtension) 然后是 @implementation CBATTRequest 和你的代码。那应该可以正常工作。
  • @RobNapier,我添加了上面的代码。
  • 您是否将CBATTRequest+Requestable.h 导入您使用的地方? (BLERequestable.h 不会告诉编译器您的类别。)您收到什么错误?

标签: objective-c runtime


【解决方案1】:

经过长时间的研究和测试(感谢 Rob Napier),我找到了错误的根源。

我的项目由一个库和可执行目标组成。在库中,我定义了我的类别并在里面使用它。问题是,当涉及到由于可执行文件的链接时,我的类别的 o 文件没有链接。见this stack post for further details on problems with categories in static libraries。

一种可能的解决方案是将 exe 目标的链接器标志设置为 -Objc。

但我不喜欢这种解决方案,因为库能否正常工作取决于 exe。

所以我在我使用它的 m 文件中包含了该类别的实现。

如果有人有另一个(更好的)解决方案,我会很高兴看到它。否则我会关闭这个问题。

【讨论】:

    猜你喜欢
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 2017-11-10
    • 1970-01-01
    相关资源
    最近更新 更多