Warum kann ich nicht erklären NSInteger mit a *
-
06-07-2019 - |
Frage
Ich versuche, meine Hand auf dem iPhone natürlich von der Stanford auf iTunes U und ich bin ein wenig verwirrt über Zeiger. In der ersten Zuweisung, habe ich versucht, so etwas wie dies zu tun
NSString *processName = [[NSProcessInfo processInfo] processName];
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];
, die einen Fehler erzeugt, nachdem blind tinkeing um, entdeckte ich, dass es die * in der NSInteger Linie war, die das Problem verursacht wurde.
So offensichtlich verstehe ich nicht, was passiert. Ich werde erklären, wie ich denke, es funktioniert und vielleicht wäre jemand so freundlich sein, die Fehler hinweisen.
Im Gegensatz zu Web-Entwicklung, habe ich jetzt brauche über das Gedächtnis, na ja, mehr als in Web-Entwicklung zu sorgen. Also, wenn ich Erstellen Sie eine Variable, wird es zugeordnet ein Bit Speicher irgendwo (RAM I annehmen). Anstelle der Weitergabe variable herum, gebe ich einen Zeiger auf dass wenig Speicher herum. Und Zeiger werden durch Voranstellen der deklarierte Variablenname mit *.
Angenommen, ich habe recht, was mir ein Rätsel ist, warum ich nicht tun müssen, dass für NSInteger?
Lösung
NSInteger
ist eine primitive Art, die es bedeutet, kann lokal auf dem Stapel gespeichert werden . Sie brauchen nicht einen Zeiger zu verwenden, darauf zuzugreifen, aber Sie können, wenn Sie wollen. Die Zeile:
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];
gibt eine Ist-Größe, nicht seine Adresse. Um dies zu beheben, müssen Sie die *
entfernen:
NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];
Sie können einen Zeiger auf ein NSInteger
haben, wenn Sie wirklich eine wollen:
NSInteger *pointerToProcessID = &processID;
Der Ampersand ist die Adresse des Betreibers. Es setzt den Zeiger auf den NSInteger
gleich die Adresse der Variablen im Speicher, anstatt die ganzen Zahl in den Variablen.
Andere Tipps
Der Grund, dass Sie nicht ausdrücklich erklären, NSInteger
mit einem *
ist, weil es nicht ein Objekt ist. Ein NSInteger ist einfach ein int
oder ein long
:
#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
endif
Wenn es in einer 32-Bit-Anwendung verwendet wird, es ist ein 32-Bit-Integer, und wenn es in einer 64-Bit-Anwendung gebaut, es ist ein 64-Bit-Integer.
Natürlich können Sie können ein NSInteger
als Zeiger übergeben, aber die meisten Funktionen einfach Argumente als NSInteger
nehmen und nicht einen Zeiger auf sie.
Objekte, auf der anderen Seite, können nur auf andere Funktionen als Zeiger übergeben werden. Dies liegt daran, Objekte Speicher für sie dynamisch zugewiesen, und so können nicht auf dem Stapel deklariert werden. Da ein int
oder long
eine feste Menge an Speicher für sie zugewiesen hat, ist dies kein Problem.
Die *
bedeutet „Zeiger“. Die Objektvariable hält einen Zeiger auf ein Objekt, so hat es eine *
; der NSInteger Variable hält einen NSInteger, nicht einen Zeiger auf einen NSInteger, so dass es nicht über einen *
. Putting das *
auf dieser Variablen gibt Ihnen zumindest eine Warnung, weil Sie eine ganze Zahl in eine Zeigervariable setzen sind.
NSInteger ist nur ein typedef für int, AFAIK.
Arbeiten mit Zeigern
NSInteger integer1 = 1;
NSLog(@"1. integer1:%ld &integer1:%p", integer1, &integer1);
//1. integer1:1 &integer1:0x7ffee59e8a98
NSInteger *integer2 = &integer1;
NSLog(@"2. integer2:%p &integer2:%p *integer2:%ld", integer2, &integer2, *integer2);
//2. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:1
*integer2 = 2;
NSLog(@"3. integer2:%p &integer2:%p *integer2:%ld \t integer1:%ld &integer1:%p", integer2, &integer2, *integer2, integer1, &integer1);
//3. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:2 integer1:2 &integer1:0x7ffee59e8a98