2012-09-20 12 views
6

W mojej klasie mam nieruchomość dispatch_queue_t zadeklarowane tak:Awaria aplikacji po aktualizacji Xcode do wersji 4.5. Przypisywanie zatrzymany obiekt do unsafe_unretained zmiennej

@property (nonatomic, assign) dispatch_queue_t queue; 

Wtedy w mojej metody init, robię:

- (id)initWithServerUrls: (NSString*)serverUrls 
{ 
    if (self = [super init]) 
    { 
     _queue = dispatch_queue_create("com.xxx.my_send_queue", DISPATCH_QUEUE_SERIAL); 
    } 

    return self; 
} 

W Xcode 4.4.1 to działało i nie spowodowało żadnych problemów (testowana aplikacja + w appstore). Teraz po uaktualnieniu do Xcode 4.5 awarii aplikacji z EXC_BAD_ACCESS i Xcode daje mi ostrzeżenie na tej linii, mówiąc:

Przypisywanie zatrzymany obiektu do zmiennej unsafe_unretained; obiekt zostanie zwolniony po przydzieleniu

Apple zaktualizował kompilator w Xcode 4.5 z LLVM 4.0 do LLVM 4.1, ale nie mam pojęcia, dlaczego mój kod się teraz psuje.

Przeszedłem przez kod i katastrofa zdarzyła się tuż po tej linii. Czy masz pomysły, co może być nie tak i jak mogę to naprawić?

ROZWIĄZANIE:

udało mi się dostać pracy z obu SDK. Właśnie dodałem:

#if OS_OBJECT_USE_OBJC 
@property (nonatomic, strong) dispatch_queue_t queue; // this is for Xcode 4.5 with LLVM 4.1 and iOS 6 SDK 
#else 
@property (nonatomic, assign) dispatch_queue_t queue; // this is for older Xcodes with older SDKs 
#endif 

nadzieję, że ktoś uzna za przydatne

+0

self._queue = dispatch_queue_create ... czy to naprawia? - dodanie "siebie." –

+0

Nie, wciąż to samo, zawiesza się, Ostrzeżenie też jest tam: – RaffAl

+0

niż" Przypisanie zatrzymanego obiektu "oznacza wynik z dispatch_queue_create (... i" do niebezpiecznej_tej zmiennej "to znaczy _ueue. A jeśli @synthetize nie robi" t rozwiązać (ponieważ jest on na Constructor) niż jakoś trzeba manipulować dispatch_queue_create (zwracana wartość, czy można umieścić ten obiekt, co on zwraca? –

Odpowiedz

13

Po pierwsze, jeśli platforma docelowa jest 5+, to gorąco polecam budynek z iOS 5 SDK. Budowanie za pomocą późniejszego zestawu SDK i ustawianie "obiektu docelowego" może działać, ale ma wiele problemów (z których żaden nie polega na tym, że nie otrzymujesz kompilatora pomagającego znaleźć miejsca, w których korzystasz z nieobsługiwanych metod). Więc odpowiedz 1: Potrzebujesz systemu iOS 5, zbuduj na systemie iOS 5 i nie powinno to mieć znaczenia.

W iOS 6, dispatch_queue_t jest obiektem ObjC. To jest wielka poprawa. Oznacza to, że możesz po prostu utworzyć dla niego właściwości strong, a ARC zajmie się resztą. Jeśli kierujesz na iOS 6, to powinno po prostu działać.

Jeśli potrzebujesz zbudować ten sam kod dla systemu iOS 5 i iOS 6, musisz wiedzieć, co to jest, aby móc zarządzać pamięcią, kiedy jej potrzebujesz, i pozostawić ją, gdy jej nie potrzebujesz. Prawidłowy test do użycia to #if OS_OBJECT_USE_OBJC. Pamiętaj, że jest to sprawdzanie w trybie kompilacji. Ma zastosowanie tylko do obsługi kodu, który chcesz napisać na różnych pakietach SDK. Dla danego SDK zachowanie będzie oddalone w ten czy w inny sposób.

Odnośnie pojęcia "niebezpieczny_zalecony" kontra "przypisać" dezorientację: w tym przypadku są one takie same. "przypisz" odnosi się tylko do nieobiektów. "unsafe_unretained" jest tym, co "assign" jest konwertowane na po zastosowaniu do obiektów. W iOS6, dispatch_queue_t jest obiektem.

Jeszcze jedno obejście, szczególnie jeśli naprawdę chcesz zachować stary kod zarządzania pamięcią podczas budowania z pakietem SDK iOS 6. Możesz przekazać -DOS_OBJECT_USE_OBJC=0 do kompilatora. To zrezygnuje z nowego modelu. Ale polecam to w ostateczności. Aby uzyskać szczegółowe informacje, zobacz os/object.h w zestawie SDK. (Cmd-Shift-O, object.h)

+0

Dzięki, to wyjaśnia dużo! – RaffAl

+0

Muszę obsługiwać obie wersje systemu iOS, dlatego użyję testu, który zaproponowałeś. Jedyne, czego teraz nie rozumiem, to jak powinienem zastąpić "@property (nonatomic, copy) CustomBlock completedBlock;" więc nie powoduje awarii aplikacji na iOS 6. Jakieś pomysły, jak ją rozwiązać? – RaffAl

+2

Pamiętaj, że jeśli pracujesz * na obu platformach, powinieneś po prostu zbudować system na iOS 5. Potrzebujesz tego tylko, jeśli potrzebujesz tego samego kodu do kompilacji w różny sposób w zależności od platformy, na której budujesz. Jeśli musisz zamienić wiersz '@ property', po prostu zapakuj go w sprawdzanie # # if (jeśli zmienna jest ustawiona, użyj' copy' .Jeśli zmienna nie jest ustawiona, użyj 'assign'.) –

Powiązane problemy