, jeśli zmienna w object_getIvar jest podstawowym typem danych (np. Float, int, bool) w jaki sposób uzyskać wartość jako funkcję zwraca wskaźnik (id) zgodnie z dokumentacją. Próbowałem casting do int, int *, ale gdy próbuję uzyskać to NSLog, otrzymuję błąd o niekompatybilny typ wskaźnika.Jak uzyskać wartość int z object_getIvar (self, myIntVar) zwracającą wskaźnik
Odpowiedz
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
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.
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? –
@Russel Zajmuję się tym i eksperymentuję. Będę edytować moją odpowiedź, jeśli coś wymyślę. –
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. –
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;
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 .... –
OK, zmieniłem go, aby użyć void *. spróbuj teraz – newacct
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. –
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)
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. –
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)
- 1. Jak uzyskać wartość int od spinnera
- 2. Jak radzić sobie z podkwerendą zwracającą więcej niż 1 wartość
- 3. Konwencje nazewnictwa: Jak nazwać metodę zwracającą wartość logiczną?
- 4. Jak przesunąć wskaźnik do wskaźnika na int?
- 5. cpp/C++ uzyskać wartość wskaźnika lub depointerize wskaźnik
- 6. Jak uzyskać metodę Java zwracającą listę rodzajową dowolnego typu?
- 7. Jak uzyskać wartość int ASCII znaku w kakao?
- 8. Jak przekonwertować int * na int
- 9. jak uzyskać wartość RatingBar
- 10. LINQ uzyskać wskaźnik globalny
- 11. jquery closest self self
- 12. Jak uzyskać wartość całkowitą z NSDictionary?
- 13. Jak powiązać z RelativeSource Self?
- 14. Używanie dispatch_async z self
- 15. Jak uzyskać wskaźnik elementu struct z interfejsu {} (odbicie). Golang
- 16. Dlaczego wskaźnik do wskaźnika (int ** a)?
- 17. Hibernate: jak wywołać funkcję przechowywaną zwracającą varchar?
- 18. Jak uzyskać wskaźnik funkcji dla wpisanej funkcji w programie?
- 19. Jak uzyskać int i modulo (mod) podziału z NSDecimalNumber
- 20. Uzyskać wybraną wartość z JXTreeTable
- 21. Jak uzyskać ten wskaźnik ze std :: function?
- 22. JavaScript indexOf() - jak uzyskać specyficzny wskaźnik
- 23. Jak uzyskać wartość numeryczną enum?
- 24. Jak uzyskać int w systemie dziesiętnym z Hex NSString
- 25. Jak przenieść posiadany wskaźnik
- 26. Jak przekonwertować wartość wyliczenia na int?
- 27. Jak uzyskać wartość UISwitch?
- 28. Jak uzyskać wartość XCUIElement?
- 29. Jak wskaźnik char być inicjowane z ciągiem znaków (tablica), ale nie int wskaźnik z tablicy liczb całkowitych?
- 30. Jak korzystać z obiektu object_getIvar i object_setIvar obiektu Object-C-Runtime w trybie szybkim?
To nie działa, ponieważ masz literówkę, jeśli zmienisz (void) i myFloatValue na (void *) & myFloatValue działa tak jak w reklamie. –
Cholera, masz rację :) – jhauberg
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. –