Hooooookay所以這裏的另一個「我只是不知道這是怎麼回事」問題:NSObject的PerformSelector問題
我第一次撥打電話下面getFullWL()
,我讓我所有的值如預期。每次後續調用,然而,返回nan
而不是真值(-nan(0x400000000)
XCode中或東西)
而且,如果我把我的「調試」行SFLog
值打印爲nan
但返回正確的值!如果我註釋掉SFLog
(這僅僅是NSLog
根據我設置的電平的#定義 - 沒有什麼特別的)在View
,那麼這個值不是由isnan()
抓到,但在Window
Window
和View
檢查爲isnan()
坐在一條線上,而DataModule
和DCMPix
正坐在另一條線上(我相信)。 DCMPix
也從Core-Data對象獲取一些數據(我相信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()
時,即使它遵循相同的執行路徑,我也不會得到nan
。 (但撥打@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);