好吧,还有一个“我只是不知道发生了什么”的问题:
当我第一次调用下面的getFullWL()时,我得到了所有预期的值。但是,随后的每个调用都返回nan而不是真值(-nan(0x400000000)在XCode或其他方面)。
此外,如果我将“调试”行放在SFLog中,则值打印为nan,但返回正确的值!如果我注释掉了SFLog (这只是NSLog的#定义,取决于我设置的级别--没有什么特殊),那么这个值不会被isnan()在View中捕获,而是在Window中被选中为isnan()
Window和View坐在一个线程上,而DataModule和DCMPix坐在另一个线程上(我相信主线程)。DCMPix还从核心数据对象(我相信是fImage)获得一些数据。
void Window::PopUp()
{
// Grab the View from the Pipe Thread and cast it to my local namespace subclass View
View *view = static_cast< View* >(getPipe()->getView(event.context.view));
float fullww = view->getFullWW();
float fullwl = view->getFullWL();
//SFLog(@"WindowLevel Window %f", wl);
// set SLider Values
if (!isnan(fullwl)){
[[vc winLevel] setMinValue:fullwl];
[[vc winLevel] setMaxValue:(-1.0f*fullwl)];
}
}
float View::getFullWL()
{
float wl = _callPixMethod(@selector(fullwl)).floatValue;
if ( isnan(wl) ) wl = _wl * 2.0f; //<-- is never detected as NaN here
//SFLog(@"WindowLevel View %f", wl); //<-- but is *printed* as NaN here
return wl;
}
// A Union to "cast" the return from the [object performSelector:] method.
// Since it returns `id` and (float)(id) doesn't work.
union performReturn {
id OBJC_ID;
int intValue;
float floatValue;
bool boolValue;
};
performReturn View::_callPixMethod(SEL method)
{
DataModule* data;
DataVisitor getdata(&data);
getConfig()->accept(getdata);
performReturn retVal;
retVal.OBJC_ID = data->callPixMethod(_datasetIndex, _datasetID, method);
return retVal;
}
id DataModule::callPixMethod(int index, std::string predicate, SEL method)
{
DCMPix *pix =[[getSeriesData(predicate) pixList_] objectAtIndex:index];
pthread_mutex_lock(&_mutex);
id retVal = [pix performSelector:method];
pthread_mutex_unlock(&_mutex);
return retVal;
}
// DCMPix.m (from API, can't change)
- (float) fullwl
{
if( fullww == 0 && fullwl == 0) [self computePixMinPixMax];
return fullwl;
}
- (void)computePixMinPixMax
{
float pixmin, pixmax;
if( fImage == nil || width * height <= 0) return;
[checking lock];
@try
{
if( isRGB)
{
pixmax = 255;
pixmin = 0;
}
else
{
float fmin, fmax;
vDSP_minv ( fImage, 1, &fmin, width * height);
vDSP_maxv ( fImage , 1, &fmax, width * height);
pixmax = fmax;
pixmin = fmin;
if( pixmin == pixmax)
{
pixmax = pixmin + 20;
}
}
fullwl = pixmin + (pixmax - pixmin)/2;
fullww = (pixmax - pixmin);
}
@catch (NSException * e)
{
NSLog( @"***** exception in %s: %@", __PRETTY_FUNCTION__, e);
}
[checking unlock];
}帮助!为什么我不能在Window中得到正确的值?
在调用view->getFullWW()时,即使它遵循相同的执行路径,也不会得到view->getFullWW()。(但是调用@selector(fullww))
不会引发错误或异常。就是那种奇怪的行为。
谢谢!
经过进一步测试后,以下更改将产生所有差异:
float View::getFullWL()
{
float wl = _callPixMethod(@selector(fullwl)).floatValue;
if ( isnan(wl) ) wl = _wl * 2.0f; //<-- is never detected as NaN here
NSLog(@"WindowLevel View %f", wl); //<-- is *printed* as NaN here
return wl; //<-- returns expected value
}
float View::getFullWL()
{
float wl = _callPixMethod(@selector(fullwl)).floatValue;
if ( isnan(wl) ) wl = _wl * 2.0f; //<-- is never detected as NaN here
return wl; //<-- returns `nan`
}经过更多的测试后,如果NSLog()语句发生在分配float fullwl =之前,那么我把它放在哪里并不重要。
void Window::PopUp()
{
// Grab the View from the Pipe Thread and cast it to my local namespace subclass View
View *view = static_cast< View* >(getPipe()->getView(event.context.view));
float fullww = view->getFullWW();
NSLog("Putting this here, makes fullwl work. Removing it, stores fullwl as nan");
float fullwl = view->getFullWL();
//SFLog(@"WindowLevel Window %f", wl);发布于 2010-07-15 14:11:14
孩子,我又在回答我自己的问题了,但答案是.RTFM。
aSelector参数应该标识不带参数的方法。对于返回对象以外的任何内容的方法,请使用NSInvocation。
所以答案是,使用NSInvocation而不是[obj performSelector:]
https://stackoverflow.com/questions/3250089
复制相似问题