Objective c 使用标量参数调用选择器

Objective c 使用标量参数调用选择器,objective-c,ios,Objective C,Ios,我目前使用objc_msgSend在对象集合上调用这样的选择器。有没有更好的办法?这是我的密码: @protocol ADelegateProtocol { -(void) timeToEventOneDidChange:(NSInterval) event1; -(void) timeToEventTwoDidChange:(NSInterval) event1; } - (void) delegatesPerformSelector:(SEL) selector withTim

我目前使用objc_msgSend在对象集合上调用这样的选择器。有没有更好的办法?这是我的密码:

@protocol ADelegateProtocol {
   -(void) timeToEventOneDidChange:(NSInterval) event1;
   -(void) timeToEventTwoDidChange:(NSInterval) event1;
}

- (void) delegatesPerformSelector:(SEL) selector withTimeIntervalAsFristParameter:(NSTimeinterval) timeInterval {
    for (id<ADelegateProtocol> delegate in delegates) {
        if([delegate respondsToSelector:selector]) {
            objc_msgSend(delegate, selector, timeInterval);
        }
    }
}
选择器作为参数传入,时间间隔是非对象值


注意:我不想使用KVO。

如果委托是NSArray:那么使用NSArray的makeObjectsPerformSelector:SELaSelector怎么样。
如果需要将对象作为参数传递,则可以使用makeObjectsPerformSelector:SELaSelector with object:idanObject。

如果委托是NSArray,那么使用NSArray的makeObjectsPerformSelector:SELaSelector怎么样。 如果需要将对象作为参数传递,可以使用makeObjectsPerformSelector:SELaSelector with object:idanObject。

在objc\u msgSend旁边可以使用的当然是NSInvocation。就我个人而言,我更喜欢objc_msgSend方式,因为它是最无开销的方式。这也是更快的方式,但这在普通应用程序中并不重要,在游戏中也很重要

好吧,这是你的选择,两种方法都有效,除了C代码在objc方法中看起来是错误的之外,objc_msgSend或NSINVOATION也没有什么不好的地方。

在objc_msgSend旁边,你可以使用的当然是NSINVOATION。就我个人而言,我更喜欢objc_msgSend方式,因为它是最无开销的方式。这也是更快的方式,但这在普通应用程序中并不重要,在游戏中也很重要

好吧,选择权在你,两种方法都可以,objc_msgSend或NSInvocation没有什么不好的,除了C代码在objc方法中看起来是错误的以外。

如果你要使用objc_msgSend,你必须创建一个正确的类型转换函数指针。依靠varargs映射到非varargs在所有情况下都不起作用

即,您希望:

void (*myMessage)(id, SEL, NSTimeInterval) = objc_msgSend;
myMessage(delegate, aSelector, aTimeInterval);
键入SO -考虑语法的近似值:p> 如果要使用objc_msgSend,必须创建一个正确的typecast函数指针。依靠varargs映射到非varargs在所有情况下都不起作用

即,您希望:

void (*myMessage)(id, SEL, NSTimeInterval) = objc_msgSend;
myMessage(delegate, aSelector, aTimeInterval);

键入SO -考虑语法的近似值:p> 请编辑问题以添加选择器作为参数传递的问题。这会产生巨大的差异。我认为如果不更改要调用的方法,它不会真正变得更好,例如,NSInvocation更乏味。如果我遗漏了什么,请原谅,但这段代码假定传递到此方法的任何选择器都将以时间间隔作为参数。如果您知道参数将是什么,为什么不知道选择器将是什么?例如,可能会传入一个选择器forBar:,该选择器以NSTimeInterval作为参数,但如果我传入一个fooBaz:,该选择器以字符串作为参数,respondsToSelector仍将返回true,但您将发送一个时间间隔,在该时间间隔中,字符串是预期的,并导致崩溃…@Jasarien:我认为这些方法可能类似于setFootTimeStamp,SetBatimesTamp等,但最好Piotr能够澄清。这很好,但如果传入任何其他具有代理可能响应的一个参数的选择器,则不会阻止程序崩溃。传递SetFootTimeStamp:或SetPartItemStamp:可以,但为了参数起见,NSObject或其任何子类将在使用Coder:后响应唤醒,如果传入时间戳,则会崩溃。我想说的是,这段代码在受控环境下可以正常工作,但并不真正安全。请编辑问题以添加选择器作为参数传递的情况。这会产生巨大的差异。我认为如果不更改要调用的方法,它不会真正变得更好,例如,NSInvocation更乏味。如果我遗漏了什么,请原谅,但这段代码假定传递到此方法的任何选择器都将以时间间隔作为参数。如果您知道参数将是什么,为什么不知道选择器将是什么?例如,可能会传入一个选择器forBar:,该选择器以NSTimeInterval作为参数,但如果我传入一个fooBaz:,该选择器以字符串作为参数,respondsToSelector仍将返回true,但您将发送一个时间间隔,在该时间间隔中,字符串是预期的,并导致崩溃…@Jasarien:我认为这些方法可能类似于setFootTimeStamp,SetBatimesTamp等,但最好Piotr能够澄清。这很好,但如果传入任何其他具有代理可能响应的一个参数的选择器,则不会阻止程序崩溃。传递SetFootTimeStamp:或SetPartItemStamp:可以,但为了参数起见,NSObject或其任何子类将在使用Coder:后响应唤醒,如果传入时间戳,则会崩溃。我想说的是,这段代码在受控环境下可以正常工作,但实际上并不安全。如果我正确理解了这个问题,那么timeInterval是一个非对象值,因此无法轻松地作为id传递。您可以将其放入对象中,例如使用NSNumber。这将失败,因为rec
eiver不会分派NSNumber,整个方法必须设计为接受NSNumber。如果我正确理解了这个问题,TIMEIVAL是一个非对象值,因此不能轻易地作为id传递。您可以将其放入对象中,例如使用NSNumber。这将失败,因为接收方不会分派NSNumber,整个方法必须设计为接受NSNumber.interest。你能告诉我为什么上面的代码更好吗?我已经检查过两个版本和xcode生成的汇编代码非常相似。您的版本:mov-0x14%ebp,%eax;调用*%eax,原始调用:调用0x13dcfe,因为ABI的详细信息可能会随着时间的推移而改变,除非存在二进制兼容性问题,而且它可能在不同的体系结构之间有所不同。你经常可以不依赖varargs就像非varargs一样,但它不是正确的、防御性的或便携的。如果有人感兴趣,这里有一个很好的简报:有趣。你能告诉我为什么上面的代码更好吗?我已经检查过两个版本和xcode生成的汇编代码非常相似。您的版本:mov-0x14%ebp,%eax;调用*%eax,原始调用:调用0x13dcfe,因为ABI的详细信息可能会随着时间的推移而改变,除非存在二进制兼容性问题,而且它可能在不同的体系结构之间有所不同。你经常可以不依赖varargs就像非varargs一样,但它不是正确的、防御性的或便携的。如果有人感兴趣,这里有一个很好的简报: