Köra kod när ett Cocoa-program startas

Tråden skapades och har fått 6 svar. Det senaste inlägget skrevs .
1

För att konkretisera mycket av det jag pratade om i tråden "Cocoa: Att greppa sammanhanget" ska jag nu börja fråga lite allmänna frågor här tänkte jag. Det jag undrar över just nu är hur jag gör för att köra kod så fort mitt Cocoa-program har startats. Jag misstänker att jag gör detta via en window controller, men jag har inte fattat hur dessa fungerar eller hur man skapar dem på ett vettigt sätt. Är det någon som har ett svar på min fråga?

  • Medlem
  • Göteborg
  • 2005-01-31 08:21

Kika i dokumentationen efter "awakeFromNib" .

mvh
b0bben

  • Medlem
  • Stockholm
  • 2005-01-31 09:25

Du kan också använda:
- (void)applicationDidFinishLaunching:(NSNotification *)notification
Då kan du anropa metoder exakt efter att du har startat applikationen.

(- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)app
och
- (void)applicationWillTerminate:(NSNotification *)notification
om du vill köra kod vid applikationens terminering.)

- (void)awakeFromNib
är bra men exekverar direkt efter den har läst in din MainMenu.nib-fil, alltså inte direkt efter att applikation har startat.

Om du utvecklar ett dokumentbaserd cocoa applikation så ska du använda windowControllerDidLoadNib och inte awakeFromNib
- (void)windowControllerDidLoadNib:(NSWindowController *) aController

Ja, alla dessa funktioner har jag hittat, men frågan är egentligen var jag ska placera dem. Om jag använder ett enda fönster i mitt program, och detta fönster inte är av en egendefinierad klass (utan ett helt vanligt NSWindow utan krusiduller), var ska jag då placera koden? Måste jag skapa en controller för det enskilda fönstret? Och isåfall, hur gör jag detta?

  • Medlem
  • Stockholm
  • 2005-02-01 10:41
Ursprungligen av alimony:

Ja, alla dessa funktioner har jag hittat, men frågan är egentligen var jag ska placera dem. Om jag använder ett enda fönster i mitt program, och detta fönster inte är av en egendefinierad klass (utan ett helt vanligt NSWindow utan krusiduller), var ska jag då placera koden? Måste jag skapa en controller för det enskilda fönstret? Och isåfall, hur gör jag detta?

Jupp, du ska skapa åtminstone en contoller (du kan också ha en controller för den View också. För ett fönster är en View. Som i Model-View-Controller. Model och View ska vara kopplade till en eller fler controller.)

Skapa en subklass av NSObject i IB som du kallar för ex. MyController och sedan instansierar du och väljer att generer kodfiler. Spara kodfilerna (.m och .h) i ditt projekt och öppna dessa i Xcode.

inne i implemenationen av klassen så lägger du till awakeFromNib eller vilken du nu vill köra.

Sök på 'awakefromnib' i AppKiDo så listar den den som AppKit INFORMAL Protocol <NSNibAwaking>:

Citat:

awakeFromNib

- (void)awakeFromNib
Prepares the receiver for service after it has been loaded from an Interface Builder archive, or nib file. An awakeFromNib message is sent to each object loaded from the archive, but only if it can respond to the message, and only after all the objects in the archive have been loaded and initialized. When an object receives an awakeFromNib message, it’s guaranteed to have all its outlet instance variables set.
Note: This method is also sent during Interface Builder’s test mode to objects instantiated from loaded palettes, which include executable code for the objects. It isn’t sent to objects defined solely by using the Classes display of the nib file window in Interface Builder.

When an Interface Builder archive is loaded into an application, each custom object from the archive is first initialized with an initWithCoder: message. It’s then more specifically initialized with the properties that it was configured with using Interface Builder. This part of the initialization process uses any setVariable: methods that are available (where Variable is the name of an instance variable whose value was set in Interface Builder). If a setVariable: method doesn’t exist, the instance variable is searched for. If it exists, the instance variable is directly set. If the instance variable doesn’t exist, initialization does not occur. Finally, after all the objects are fully initialized, each receives an awakeFromNib message.

The order in which objects are loaded from the archive is not guaranteed. Therefore, it’s possible for a setVariable: message to be sent to an object before its companion objects have been unarchived. For this reason, setVariable: methods should not send messages to other objects in the archive. However, messages to other objects can safely be sent from within awakeFromNib—by which time it’s assured that all the objects are unarchived and initialized (though not necessarily awakened, of course).

Typically, awakeFromNib is implemented for classes whose instances are used as the owners of a loaded nib file (shown as “File’s Owner” in Interface Builder). Such a class has the express purpose of connecting the loaded objects with objects in the application and can thereafter be disposed of, or remain in the capacity of a controller or coordinator for the loaded objects. For example, suppose that a nib file contains two custom views that must be positioned relative to each other at runtime. Trying to position them when either one of the views is initialized (in initWithCoder: or a setVariable: method) might fail, since the other views might not be unarchived and initialized yet. However, it can be done in the nib file owner’s awakeFromNib method (firstView and secondView are outlets of the file’s owner):

- (void)awakeFromNib{

    NSRect viewFrame;


    if ([[self superclass] instancesRespondToSelector:@selector(awakeFromNib)]){

        [super awakeFromNib];

    }

    viewFrame = [firstView frame];

    viewFrame.origin.x += viewFrame.size.width;

    [secondView setFrame:viewFrame];

    return;

}

Note the testing of the superclass before invoking its implementation of awakeFromNib. The Application Kit declares a prototype for this method, but doesn’t implement it. Because there’s no default implementation of awakeFromNib, be sure to invoke it only when the object does in fact respond.

See Also: + loadNibNamed:owner: (NSBundle Additions), - awakeAfterUsingCoder (NSObject class), - initWithCoder: (NSCoding protocol), + initialize (NSObject class)

Och följ instruktionerna där.

Gör samma sak med: applicationDidFinishLaunching osv. om du vill tillämpa dessa också.

Lycka Till!

Tackar tackar!

  • Medlem
  • Stockholm
  • 2005-02-01 18:08
Ursprungligen av alimony:

Tackar tackar!

varsågod

1
Bevaka tråden