如何使用 @selector 和 NSInvocation 从另一个对象调用 NSManaged 对象的 @dynamic 方法?

Posted

技术标签:

【中文标题】如何使用 @selector 和 NSInvocation 从另一个对象调用 NSManaged 对象的 @dynamic 方法?【英文标题】:How do I call NSManaged object's @dynamic method from from another object using a @selector and NSInvocation? 【发布时间】:2009-10-15 01:59:04 【问题描述】:

这里是可可新手。我正在开发一个基于 iPhone UITableViewController 的小部件,该小部件可用于在启动期间编辑对象集中的日期和文本属性。目前,我正在尝试使用@selector 和 NSInvocation 来执行此操作,如下所示。 注意:“targetObject”是控制器初始化时设置的对象。

- (IBAction)saveDate:(id)sender 
      //The selector below would normally be passed in when the controller is initialized
      [self setDoneSelector:@selector(setDate:)];
      NSMethodSignature * sig = nil;
      sig = [[targetObject class] instanceMethodSignatureForSelector:[self doneSelector]];
      NSInvocation * myInvocation = nil;
      myInvocation = [NSInvocation invocationWithMethodSignature:sig];
      [myInvocation setTarget:targetObject];
      [myInvocation setSelector:doneSelector];
      NSDate * myDate = [datePicker date];
      [myInvocation setArgument:&myDate atIndex:2];
      NSString * result = nil; 
      [myInvocation retainArguments]; 
      [myInvocation invoke];

这在大多数对象上都可以正常工作,但是在将核心数据 (NSManagedObject) 作为 targetObject 传递时遇到了麻烦。对象如下所示:

事务.h

#import <CoreData/CoreData.h>

@interface Transaction :  NSManagedObject  



@property (nonatomic, retain) NSString * message;
@property (nonatomic, retain) NSDate * date;

@end

交易.m

#import "Transaction.h"

@implementation Transaction 

@dynamic message;
@dynamic date;

@end

如果我在控制器中将此对象设置为目标对象,我可以直接调用“setDate:”方法而不会出现问题。

[targetObject setDate:[datePicker date]];

但是当我尝试使用@selector 调用它时,我得到'程序接收信号:“EXC_BAD_ACCESS”。'

我想这与 NSManagedObject 中使用的 @dynamic 方法以及它们的创建时间有关,但我对该过程知之甚少,不知道如何或是否可以解决此问题以使其正常工作。我已经尝试在 Transaction 对象中显式创建“setDate:(NSDate *)aDate”方法,并且该方法有效,但我想知道我是否应该这样做以及如何使用 NSManagedObject。

我可以在不明确定义的情况下使用@selector 访问这些setter 方法吗?

【问题讨论】:

为什么需要为此使用 NSInvocation? 澄清一下:NSObject 的 performSelector 系列消息在哪些方面不足以满足您的需求?很少有人需要使用 NSInvocation,我看不出有什么理由让你成为这个 sn-p 中的一员。 【参考方案1】:

在这里与 NSD 达成一致。您应该首先将此代码简化为更简单的-performSelector:withObject: 版本:

- (IBAction)saveDate:(id)sender 
      [self.targetObject performSelector:self.doneSelector withObject:[self.datePicker date]];

如果仍然有问题,我们可以开始调试真正的问题所在。 NSInvocation 是解决这类简单问题的一个非常花哨的对象。

如果您仍然遇到崩溃,那么您需要查看实际的堆栈跟踪,以了解哪些变量未正确初始化或过度释放。

【讨论】:

第二。并且 EXEC_BAD_ACCESS 几乎总是在已释放的对象上调用方法。 (也许是一个超过其托管对象上下文或其他东西的指针?) 哇,我不敢相信我没有深入挖掘来找到更简单的方法。它看起来过于复杂,但我被锁定在 NSInvocation 上。此方法似乎可以消除 EXC_BAD_ACCESS 错误。简单、优雅、实用。我喜欢!谢谢大家。

以上是关于如何使用 @selector 和 NSInvocation 从另一个对象调用 NSManaged 对象的 @dynamic 方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift #selector 语法解决“歧义使用”编译错误?

关于@selector的xcode语法问题

如何让 SYCL“default_selector”选择 Intel GPU 而不是 NVIDIA GPU?

如何让 SYCL“default_selector”选择 Intel GPU 而不是 NVIDIA GPU?

如何在UiPath selector中添加变量

如何在交互式网格中将 APEX$ROW_SELECTOR 与动态操作一起使用