Защо този код се срива, когато се компилира с Apple LLVM, но не и в LLVM/GCC?

Опитвам се да получа този код: http://code.google.com/p/switchcontrol/source/browse/trunk/code/AFSwitchControl.m компилиране под Apple LLVM в Xcode 4.5.2. Работи, когато се компилира с LLVM/GCC, но се срива в метода mouseDown, когато се превключи към Apple LLVM на ред 198:

NSRect knobRect = _AFSwitchControlKnobRectForInsetBackground(slotRect, _offset);

Тъй като _offset не е зададено. Предполага се, че е зададено в метода за свързване с този ред:

[self setOffset:(CGFloat)[self state]];

Но изглежда, че нищо не се задава под LLVM по някаква причина. Моето обвързващо обаждане изглежда така:

[control bind:NSValueBinding toObject:self withKeyPath:@"isToggleSwitchOn" options:nil];

Някакви идеи защо състоянието на контролата не връща нищо под LLVM? Благодаря!


person K_T    schedule 22.11.2012    source източник


Отговори (1)


Проблемът всъщност е няколко реда по-горе, в извикването на _AFSwitchControlPartRects.

- (void)mouseDown:(NSEvent *)event {
    NSRect textRect, backgroundRect;
    _AFSwitchControlPartRects([self bounds], &textRect, &backgroundRect);

    NSRect slotRect = _AFSwitchControlInsetBackgroundRect(backgroundRect);
    NSRect knobRect = _AFSwitchControlKnobRectForInsetBackground(slotRect, _offset);

Вторият аргумент на _AFSwitchControlPartRects, &textRect е указател към правоъгълник.

При изпълнението на функцията обаче този параметър трябва да бъде указател към достатъчно място за два правоъгълника.

NS_INLINE void _AFSwitchControlPartRects(NSRect bounds, NSRect *textRects, NSRect *backgroundRect) {
    NSDivideRect(bounds, textRects, backgroundRect, NSWidth(bounds)/5.0, NSMinXEdge);

    textRects[1] = _AFSwitchControlInsetTextRect(NSOffsetRect(textRects[0], NSWidth(*backgroundRect), 0));
    textRects[0] = _AFSwitchControlInsetTextRect(textRects[0]);

Когато това пише в textRects[1], то драска върху стека на -mouseDown. Препълване на буфера.

Струва ми се, че това се случва с изтриване на себе си, така че следващото дерефериране на себе си ще умре. Това се случва да бъде използването на _offset.

person Ken    schedule 22.09.2013
comment
Благодаря! Промених го на NSRect textRect[2] и вместо това извиках _AFSwitchControlPartRects([self bounds], textRect, &backgroundRect). - person K_T; 23.09.2013