代码之家  ›  专栏  ›  技术社区  ›  Stephen Furlani

nsObject PerformSelector问题

  •  0
  • Stephen Furlani  · 技术社区  · 15 年前

    Hooooookay这是另一个 “我只是不知道发生了什么事” 问题:

    我第一次打电话给 getFullWL() 下面,我得到了我所有的期望值。但是,每次后续调用都会返回 nan 而不是真值( -nan(0x400000000) 在Xcode或其他地方)

    此外,如果我将“调试”行放入 SFLog 值打印为 但返回正确的值! 如果我发表评论 斯弗洛格 (这只是一个定义 NSLog 根据我设置的级别-无特殊),则该值不会被捕获 isnan() 在里面 View 但是被检查为 ISNN() 在里面 Window

    窗口 视图 坐在一根线上,而 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];
    }
    

    救命!为什么我不能得到正确的值 窗口 ?

    我也没有 打电话的时候 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);
    
    1 回复  |  直到 15 年前
        1
  •  1
  •   Stephen Furlani    15 年前

    小鬼,我来回答我自己的问题 再一次 但答案是… RTFM .

    aselector参数应标识不接受参数的方法。对于返回对象以外的任何内容的方法,请使用 NSInvocation .

    所以答案是,使用 NSInvocation 而不是 [obj performSelector:]

    推荐文章