Skicka meddelande till self i awakeFromNib

Tråden skapades och har fått 12 svar. Det senaste inlägget skrevs .
1
  • Medlem
  • Stockholm
  • 2007-04-03 22:22

Som jag har förstått det bör man inte skicka meddelande till objekt i samma hierarki (i vilken väl self ingår) i awakeFromNib. Jag får iaf problem när jag skickar meddelande till self i awakeFromNib.

Är jag ute och cyklar som vanligt, eller är det ovanstående som är problemet? Metoden fungerar när jag kallar den från self från andra metoder.

Finns det något sätt att kalla en metod per automatik senare än awakeFromNib?

Vänligen, Ylan

  • Medlem
  • Stockholm
  • 2007-04-03 22:25

Också koden

#import "MyController.h"

@implementation MyController
- (void)awakeFromNib
{
	myColorPanel = [NSColorPanel sharedColorPanel];
	
	[myColorPanel setTarget:self];
	[myColorPanel setAction: NSSelectorFromString(@actionChangeColor)];
	[myColorPanel orderFront:nil];
	[self changeColor];//Här blir det problem!!
}


- (void)actionChangeColor
{
	[self changeColor];//Men inte här!!
}	

- (void)changeColor
{
	[myWindow setBackgroundColor: [myColorPanel color]];
	[myWindow display];	
	[redComponentTextField setFloatValue: [[myColorPanel color] redComponent]];
	[greenComponentTextField setFloatValue: [[myColorPanel color] greenComponent]];
	[blueComponentTextField setFloatValue: [[myColorPanel color] blueComponent]];
}
@end

Du kan skicka meddelanden till self i awakeFromNib. Problemet uppkommer då du försöker köra:

[redComponentTextField setFloatValue: [[myColorPanel color] redComponent]];
[greenComponentTextField setFloatValue: [[myColorPanel color] greenComponent]];
[blueComponentTextField setFloatValue: [[myColorPanel color] blueComponent]];
  • Medlem
  • Stockholm
  • 2007-04-03 22:44
Ursprungligen av Marcus K:

Du kan anropa metoder i self från awakeFromNib. Problemet uppkommer då du försöker köra:

[redComponentTextField setFloatValue: [[myColorPanel color] redComponent]];
[greenComponentTextField setFloatValue: [[myColorPanel color] greenComponent]];
[blueComponentTextField setFloatValue: [[myColorPanel color] blueComponent]];

Och problemet är att jag kör det innan allt är redo? Finns det något sätt att köra det automatiskt så fort det är möjligt?

Denna fantastiskt snabba respons slår mig med häpnad!

Tack!

Vänligen, Ylan

Senast redigerat 2007-04-04 06:53
  • Medlem
  • Simrishamn
  • 2007-04-04 11:23

Hmm? Poängen med -awakeFromNib är ju just att meddelandet skickas så fort nib:en är färdigladdad, d.v.s. då outlets och actions är connectade, och bindings gjorda i IB är aktiverade....

EDIT: dessutom, vad för typ av problem är det du får? En exception i loggen? Programmet dör? Datorn börjar utstöta konstiga ljud? Eller händer det helt enkelt ingenting alls...?

  • Medlem
  • Mölndal
  • 2007-04-04 11:41

Ylan, jag hoppas jag inte påpekar något uppenbart nu, men har du provat att använda XCodes debugger? Där kan du lätt se var saker och ting går snett och behöver inte gissa vilken rad som bråkar!

  • Medlem
  • Stockholm
  • 2007-04-04 21:34
Ursprungligen av memark:

Ylan, jag hoppas jag inte påpekar något uppenbart nu, men har du provat att använda XCodes debugger? Där kan du lätt se var saker och ting går snett och behöver inte gissa vilken rad som bråkar!

Ingen fara, blir hellre upplyst om det uppenbara, än förblir oupplyst om det, för mig ouppenbara!

Jag vet att det är raden

[redComponentTextField setFloatValue: [[myColorPanel color] redComponent]];

som får det hela att krascha. Närmare bestämt när jag skickar redComponent till [myColorPanel color]s returnerade NSColor, då [myColorPanel color] fungerar två rader tidigare.

Jag vet också att samma meddelande fungerar utmärkt någon bråkdels sekund senare.

Kan man inte då misstänka att problemet består i att "allt inte är färdigt"? Om så är fallet, vet någon om man när och hur man kan skicka meddelandet automatiskt så tidigt som möjligt?

Vänligen, Ylan

  • Medlem
  • Stockholm
  • 2007-04-04 22:19

Ojdå,

Jag lade till följande rad [myWindow setFrame:[[NSScreen mainScreen] visibleFrame] display:YES animate:YES]; före [self changeColor]; i awakeFromNib, och nu fungerar det!

Kan det bero på tidsfaktorn, eller är det något annat som händer?

För det fall någon är intresserad (pallar kolla), finns projektet här!

Vänligen, Ylan

  • Medlem
  • Stockholm
  • 2007-04-04 22:25

Visade sig att endast debugbygget fungerade, ej releasebygget!

Vänligen, Ylan

Varför har du en instans variabel för NSColorPanel när det är en singleton? Din appliktion har bara en instans av den så du kan tab bort myColorPanel och istället använda [NSColorPanel sharedColorPanel] direkt.

Joakim

  • Medlem
  • Stockholm
  • 2007-04-05 09:27
Ursprungligen av jocked:

Varför har du en instans variabel för NSColorPanel när det är en singleton? Din appliktion har bara en instans av den så du kan tab bort myColorPanel och istället använda [NSColorPanel sharedColorPanel] direkt.

Joakim

Helt enkelt för att jag labbar. Finns det något problem, förutom onödigheten?

Vänligen, Ylan

Om du kikar i Xcode run log när du startar ditt program kan man se följande:

2007-04-05 10:12:17.194 windowsColourTest[27449] An uncaught exception was raised
2007-04-05 10:12:17.209 windowsColourTest[27449] *** -redComponent not defined for the NSColor NSCalibratedWhiteColorSpace 1 1; need to first convert colorspace.
2007-04-05 10:12:17.209 windowsColourTest[27449] *** Uncaught exception: <NSInvalidArgumentException> *** -redComponent not defined for the NSColor NSCalibratedWhiteColorSpace 1 1; need to first convert colorspace.

Du kan läsa mer om color spaces här, men lite kort kan man säga att du har fått en färg i en color space där du inte kan be om röda komponenten, och du måste konvertera den till något annat, lämpligen NSCalibratedRGBColorSpace:

- (void)changeColor
{
	NSColor		*color;
	
	color = [[myColorPanel color] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
	
	[myWindow setBackgroundColor: color];
	[myWindow display];	
	
	[redComponentTextField setFloatValue: [color redComponent]];
	[greenComponentTextField setFloatValue: [color greenComponent]];
	[blueComponentTextField setFloatValue: [color blueComponent]];
}

Det finns lite andra problem i din kod dock. Nån annan har redan tagit upp problemet med att ha en instansvariabel till NSColorPanel +sharedColorPanel. Nu råkar den vara en singleton så det fungerar, men det är mycket möjligt att den skulle kunna byta ut sig själv mot en annan instans av NSColorPanel senare, och då har du en sparad pekare till något som är deallokerat. Bättre att fråga efter +sharedColorPanel i varje metod du behöver använda den istället.

Din metod actionChangeColor tar ingen parameter, men actions ska alltid ta en parameter, sender. Definierar om den till - (void)actionChangeColor: (id)sender. Notera att actionChangeColor och actionChangeColor: är helt olika metoder. Du använder även NSSelectorFromString() i -setAction:, när du kan (och bör) använda @selector() istället:

[myColorPanel setAction: @selector(actionChangeColor:)];
  • Medlem
  • Stockholm
  • 2007-04-06 12:02

Tack alla, för all hjälp!

Vänligen, Ylan

1
Bevaka tråden