Anlamsal Sorun: Mülkün sentezlenen alıcısı, 'sahip olunan' nesneleri döndürmek için Kakao adlandırma kuralını izler


283

Şu anda uygulamamı geliştirmeye çalışırken iOS 5 SDK'sını kullanıyorum. Bir NSString özelliği yapmak ve sonra .m dosyasında (ben bunu daha önce hiçbir sorun ile yaptım) sentezlemek için çalışıyorum. Şimdi bununla karşılaştım: "Anlamsal Sorun: Mülkün sentezlenen alıcısı," sahip olunan "nesneleri döndürmek için Kakao adlandırma kuralını izliyor."

Bu benim kodum: .h

@interface ViewController : UIViewController {
     NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;

.m

@synthesize newTitle;

Bunu nasıl çözebileceğime dair bir ipucu var mı? Teşekkürler!!


Ben çok benzer bir hata vardı "Mülkiyet 'ait' nesneleri döndürmek için Kakao adlandırma kuralları takip" Bavyera'nın cevabı feryat bu da çözmek gibi görünüyor.
TMin

Yanıtlar:


606

Tahminimce kullandığınız derleyici sürümü , bildirilen özellikler için bellek yönetimi kurallarına da uyuyor - daha spesifik olarak bildirilen özelliklerin erişimcileri için:

Adı “ayır”, “yeni”, “kopya” veya “mutableCopy” ile başlayan bir yöntem kullanarak oluşturursanız, bir nesnenin sahipliğini alırsınız.

Adlandırılmış bir özellik newTitle, sentezlendiğinde, adı verilen bir yöntem verir -newTitle, bu nedenle uyarı / hata verir. -newTitleözelliğinin bir alıcı yöntemi olduğu varsayılır newTitle, ancak adlandırma kuralları, adı ile başlayan bir yöntemin newarayan tarafından sahip olunan bir nesneyi döndürdüğünü belirtir (alıcı yöntemi değil).

Bunu şu şekilde çözebilirsiniz:

  1. Bu mülkü yeniden adlandırmak:

    @property (strong, nonatomic) NSString *theNewTitle;
  2. Mülk adını tutmak ve özel yöntem adı öneklerinden biriyle başlamayan bir alıcı adı belirtmek:

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  3. Hem mülk adını hem de alıcı adını tutmak ve derleyiciye, alıcı adı başlasa bile new, noneyöntem ailesinin aksine yöntem ailesine ait olduğunu söylemek new:

    #ifndef __has_attribute
    #define __has_attribute(x) 0  // Compatibility with non-clang compilers
    #endif
    
    #if __has_attribute(objc_method_family)
    #define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
    #else
    #define BV_OBJC_METHOD_FAMILY_NONE
    #endif
    
    @interface ViewController : UIViewController
    @property (strong, nonatomic) NSString *newTitle;
    - (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
    @end

    Bu çözüm, newTitlehem özellik adı hem de alıcı adı olarak kalmanıza izin verse de -newTitle, arayanın sahip olduğu bir nesneyi döndürmeyen bir yönteme sahip olmanın , kodunuzu okuyan diğer insanlar için kafa karıştırıcı olabileceğini unutmayın.


Kayıt için Apple, ARC Sürüm Notlarına Geçiş'i yayınladı ve yayınladıkları :

Bir özelliğe newveya ile başlayan bir ad veremezsiniz copy.

İfadelerinin tam olarak doğru olmadığı konusunda bilgilendirildiler: suçlu, mülk adı değil, alıcı yöntemi adıdır.


Düzenleme 17 Ocak 2015: Clang'a , yeniobjc_method_family(none) bir özellik adının özel yöntem ailesi öneklerinden biriyle eşleştiği genel durum için, bir düzeltme aracı da dahil olmak üzere yukarıdaki 3. seçeneği öneren kısa bir taahhüt gördüm . Xcode büyük olasılıkla bu değişikliği eninde sonunda dahil edecektir.


6
Bir cazibe adam gibi çalıştı !! Teşekkürler!!! Gelecekte başvurmak için - "@property (güçlü, anatomik olmayan, getter = theNewTitle) NSString * newTitle;"
Noam

8
Harika cevap. Ben "yeni" önek değişkenleri vardı.

Ben de bu problemi yaşadım ve çok zamanımı boşa harcıyor! Gerçekten bir dahisin ~ Teşekkürler!
H Lai

NS_RETURNS_NOT_RETAINEDsenin de ihtiyacın olan şey bu.
DawnSong

55

Kabul Edilemez Nesne İsimleri

  • newButton
  • copyLabel
  • allocTitle

Kabul Edilebilir Nesne İsimleri

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc # otomatik sentezlenmiş # xcode-4.6.1

** DÜZENLE **

Görünüşe göre mutableCopy de kullanamazsınız .


1
Ayrıca "kopya" nın şimdilik kullanılamadığını fark ettim.
Rishab

30

Yeni ile başlayan üyenin adı uyarıyı tetikleyen şeydir. Adı editedTitle olarak değiştirin, uyarı kaybolacaktır. Bunu doğrulayan belgeleri bulamadım, ancak test yoluyla 'yeni' ile başlayan üye değişkenlerin derleyiciyi ağırlaştırdığını belirleyebildim.


8

ARC, özellik adında "Yeni ...." kullanılmasına izin vermez. ancak alıcı adını değiştirerek "newTitle" kullanabilirsiniz.

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;

6

Bavyera'nın ne yapmak istediğini önerdiği gibi görünmüyor. Tüm yapmak istediğiniz bir örnek değişkeni bildirip NewTitleözelliği sentezlemektir. Eskiden örnek değişkeni ve özelliği bildirmeliydik. Daha fazla yok.

Şimdi, bunu yapmanın doğru yolunun şu olduğuna inanıyorum:

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage

Özellik için örnek değişkeni newTitlesentezlenir. Örnek değişkeninizin mülkünüzle aynı olmasını istemezsiniz - hata yapmak çok kolay .

Örneğe bakın : Özelliklerin Bildirilmesi ve Erişimcilerin Sentezlenmesi


Bu derleyici sürümüne bağlıdır. Bu durumda clang'ın son sürümleri bir uyarı veriyor, bu yüzden cevabımda derleyici sürümünden bahsetmiştim.

Sorunu çözdüğünü sanmıyorum. Xcode 9 için bir uyarı değil, bir hata. NS_RETURNS_NOT_RETAINEDihtiyacınız olan şey bu.
DawnSong

4

CoreData'da öznitelikte "normal ..." kullanırsanız (normal olarak derleyin) "kötü erişim" özel durumu ile rasgele kilitlenir.

Çökme günlüğü yoktur ve "Tüm İstisnalar Kesme Noktası" ile gösterilen çizgi size hiç yardımcı olmaz.


3

Özelliğin adıyla aynı olan bir ayarlayıcıyı manuel olarak yazmak bu uyarıyı kaldırdı.


Xcode 7.3'te bu yardımcı olmadı. Özellik tanımı satırında hala bir hata görünüyor.
arlomedia

1

Mülk adlarının önünde "yeni" kullanmanız / kullanmamanız gereken sorunun yanı sıra, bir şey daha söyleyelim: Genel olarak adların önünde "yeni" olmamasına çalışın. "Yeni" zamana bağlıdır. Şu anda sizin için yeni, ama bir süre sonra tekrar yeni bir şey uygulamak isteyebilirsiniz. Yani isimlerde "yeni" kullanmak her zaman kötüdür. Şu şekilde düşünmeye çalışın: Programlama dünyasında, "yeni" her zaman bir şeyler yaratır: bir şeyin yeni bir örneği.

Durumunuzda farklı bir başlık atamak istediğinizde geçerli adın mülkiyet başlığıReplacement.

Bir şey daha var: setSomething veya getSomething gibi, önce fiil ile işlevleri ve yöntemleri adlandırmaya çalışın. Ancak özelliklerde, öncelikle, heightMinimum, heightMaximum, vb. Gibi bir nesneyi adlandırmaya çalışın -> kodlarken denetçinizi kullandığınızda, her zaman nesneleri ararsınız. Denemek. ;-)


1

NS_RETURNS_NOT_RETAINED adlandırma problemini çözmek için kullanılır.

@property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;

Biz onun bulabilirsiniz tanımını şu şekilde

#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

'Ns_returns_not_retained' özniteliği, 'ns_returns_retained' ın tamamlayıcısıdır. Bir işlev veya yöntemin Kakao kurallarına uyduğu ve tutulan bir Kakao nesnesini döndürdüğü durumlarda, bu öznitelik, döndürülen nesne başvurusunun, arayan kişiye döndürülen bir "sahip olma" başvurusu olarak kabul edilmemesi gerektiğini belirtmek için kullanılabilir. Temel çerçevesi, aşağıda gösterilene işlevsel olarak eşdeğer olan bir NS_RETURNS_NOT_RETAINED makrosunu tanımlar.

Buraya daha fazla ayrıntı ekleyin .


-2

bunu dene:-

@property (nonatomic,retain) NSString *newTitle;

1
Yine de aynı konu. Bilginize, hata satırı synthesize satırında.
Noam
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.