2009-08-01 8 views

Odpowiedz

6

Pierwsze:

myFloat = 2.34f; 

float myFloatValue; 
object_getInstanceVariable(self, "myFloat", (void*)&myFloatValue); 

NSLog(@"%f", myFloatValue); 

Wyjścia:

2,340000

Ustawianie:

float newValue = 2.34f; 
unsigned int addr = (unsigned int)&newValue; 

object_setInstanceVariable(self, "myFloat", *(float**)addr); 

NSLog(@"%f", myFloat); 

Wyjścia:

2,340000

+2

To nie działa, ponieważ masz literówkę, jeśli zmienisz (void) i myFloatValue na (void *) & myFloatValue działa tak jak w reklamie. –

+0

Cholera, masz rację :) – jhauberg

+0

Jakieś pomysły na object_setInstanceVariable for a float? Mogę go uruchomić dla int poprzez int myInt = 5; int theInt; object_setInstanceVairable (self, "theInt", (void *) myInt); , ponieważ wskaźniki i numery wewnętrzne mają ten sam rozmiar, więc nie działa dla elementów pływających. –

-1

Prawdopodobnie boksuje wartość w NSNumber. Można to sprawdzić przez NSLogging className Zwracany id przez, na przykład tak:

id returnedValue = object_getIvar(self, myIntVar); 
NSLog(@"Class: %@", [returnedValue className]); 

Edit: Znalazłem jeszcze jedno pytanie tylko jak ten tutaj: Handling the return value of object_getIvar(id object, Ivar ivar)

Z własnego eksperymentowania, wydaje się, że mój oryginalny założenie był nieprawidłowy. int i float oraz inne prymitywy wydają się zwracane jako rzeczywista wartość. Jednak byłoby właściwe użycie ivar_getTypeEncoding w celu sprawdzenia, czy zwrócona wartość jest typem, którego oczekuje się, że jest.

+0

gdy próbuję zadzwonić [returnedValue className] Otrzymuję ostrzeżenie, że nie znaleziono metody className. Następnie spróbowałem użyć object_getClassName (object_getIvar (self, myIntVar)) (myIntVar jest faktycznie przydzielany w pętli for, więc się zmienia) i pętla jest wykonywana raz, a następnie kończę w GDB, ale nie ma żadnego błędu zarejestrowanego. Jedyną wartością, która zostanie zarejestrowana, jest "zero" ... pomysłów? –

+0

@Russel Zajmuję się tym i eksperymentuję. Będę edytować moją odpowiedź, jeśli coś wymyślę. –

+0

Jacob sprawił, że działał przy użyciu object_getInstanceVariable, ale nadal jestem ciekawy jak uzyskać object_getIvar do działania, ponieważ jest najwyraźniej szybszy (http://developer.apple.com/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html # // apple_ref/c/func/object_getIvar) Próbowałem przeszukiwać sieć na przykładach z użyciem go, ale nikt nie używa go z podstawowymi typami. –

-1

można użyć object_getInstanceVariable bezpośrednio (nie testowałem)

void *ptr_to_result; 
object_getInstanceVariable(obj, "intvarname", &ptr_to_result); 
float result = *(float *)ptr_to_result; 
+0

Dostaję niekompatybilny wskaźnik czasu na 3. argument .... Nie jestem strasznie zaznajomiony z Obj-C obawiam się. doktorzy mówią, że to powinien być wskaźnik pustki, to jest to samo jak id myślę? w takim przypadku wracam do tego samego problemu co powyżej .... –

+0

OK, zmieniłem go, aby użyć void *. spróbuj teraz – newacct

+0

teraz wychodzi do GDB na ostatniej linii bez wiadomości, dlaczego, kompiluje się bez ostrzeżeń jednak. Jeśli uderzę dalej w tej linii, otrzymam "EXC_BAD_ACCESS", co moim zdaniem jest związane z zarządzaniem pamięcią. Jakieś dalsze myśli? BTW Sprawdzam, czy mój var typEncoding = "f" przed tym, więc nie może być spowodowane niedopasowaniem zmiennych/alokacji pamięci itp. Przynajmniej nie sądzę tak. –

2

Wartość, która jest zwracana jest wartość z właściwym miejscu w obiekcie; po prostu nie jest to właściwy typ. Dla int i BOOL (ale nie float), można po prostu rzucić wskaźnik do int lub BOOL, ponieważ wskaźniki i ints są tej samej wielkości i mogą być oddane do siebie:

(int)object_getIvar(obj, myIntVar) 
+0

wydaje się to jednak działać .... mogę użyć case na typeEncoding do obsługi Bools i Ints, ale dla float wciąż szukam rozwiązania. –

3

Dla łuku:

Zainspirowany tej odpowiedzi: object_getIvar fails to read the value of BOOL iVar. Musisz wywołać wywołanie funkcji object_getIvar, aby uzyskać ivars typu podstawowego.

typedef int (*XYIntGetVariableFunction)(id object, const char* variableName); 
XYIntGetVariableFunction intVariableFunction = (XYIntGetVariableFunction)object_getIvar; 
int result = intVariableFunction(object, intVarName); 

Zrobiłem małą przydatnych makro dla szybkiego definicji tych wskaźników funkcji:

#define GET_IVAR_OF_TYPE_DEFININTION(type, capitalized_type) \ 
typedef type (*XY ## capitalized_type ## GetVariableFunctionType)(id object, Ivar ivar); \ 
XY ## capitalized_type ## GetVariableFunctionType XY ## capitalized_type ## GetVariableFunction = (XY ## capitalized_type ## GetVariableFunctionType)object_getIvar; 

Następnie dla podstawowych typów należy określić połączenia do makro (np params(Long long, longlong) zmieści):

GET_IVAR_OF_TYPE_DEFININTION(int, Int) 

A potem funkcję do odbierania int (lub określony) Typ zmienna stają się dostępne:

int result = XYIntGetVariableFunction(object, variableName) 
Powiązane problemy