2010-07-14 70 views
0

Hooooookay所以这里的另一个“我只是不知道这是怎么回事”问题:NSObject的PerformSelector问题

我第一次拨打电话下面getFullWL(),我让我所有的值如预期。每次后续调用,然而,返回nan而不是真值(-nan(0x400000000) XCode中或东西)

而且,如果我把我的“调试”行SFLog值打印为nan但返回正确的值!如果我注释掉SFLog(这仅仅是NSLog根据我设置的电平的#定义 - 没有什么特别的)在View,那么这个值不是由isnan()抓到,但在Window

WindowView检查为isnan()坐在一条线上,而DataModuleDCMPix正坐在另一条线上(我相信)。 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); 

回答

1

雏龙,在这里,我回答我的问题再次但得到的答复是... RTFM

aSelector参数应该标识一个不带参数的方法。对于返回除对象以外的任何其他方法的方法,请使用NSInvocation

因此,答案是,使用NSInvocation而不是[obj performSelector:]