Masalah Semantik: Pembuat properti yang disintesis mengikuti konvensi penamaan Kakao untuk mengembalikan benda-benda 'milik'

283

Saat ini saya menggunakan iOS 5 SDK yang mencoba mengembangkan aplikasi saya. Saya mencoba membuat properti NSString, dan kemudian mensintesisnya dalam file .m (saya telah melakukan ini sebelumnya tanpa masalah). Sekarang, saya menemukan ini: "Masalah Semantik: Pembuat properti yang disintesis mengikuti konvensi penamaan Kakao untuk mengembalikan objek 'milik'."

Ini adalah kode saya: .h

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

.m

@synthesize newTitle;

Adakah yang tahu bagaimana saya bisa memperbaikinya? Terima kasih!!

Noam
sumber
Saya memiliki kesalahan yang sangat mirip, "Properti mengikuti konvensi penamaan Kakao untuk mengembalikan benda-benda 'milik'," jawab Bavarious di bawah ini tampaknya juga memecahkan masalah ini.
TMin

Jawaban:

606

Dugaan saya adalah bahwa versi kompiler yang Anda gunakan mengikuti aturan manajemen memori untuk properti yang dideklarasikan juga - lebih khusus, untuk pengakses properti yang dideklarasikan:

Anda mengambil kepemilikan atas suatu objek jika Anda membuatnya menggunakan metode yang namanya dimulai dengan "alokasi", "baru", "salin", atau "mutableCopy".

Properti bernama newTitle, ketika disintesis, menghasilkan metode yang disebut -newTitle, maka peringatan / kesalahan. -newTitleseharusnya menjadi metode pengambil untuk newTitleproperti, namun konvensi penamaan menyatakan bahwa metode yang namanya dimulai dengan newmengembalikan objek yang dimiliki oleh penelepon, yang bukan kasus metode pengambil.

Anda dapat menyelesaikan ini dengan:

  1. Mengganti nama properti itu:

    @property (strong, nonatomic) NSString *theNewTitle;
  2. Menyimpan nama properti dan menentukan nama pengambil yang tidak dimulai dengan salah satu awalan nama metode khusus:

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  3. Menjaga nama properti dan nama pengambil, dan memberi tahu kompiler bahwa, meskipun nama pengambil dimulai new, itu milik nonekeluarga metode yang bertentangan dengan newkeluarga metode:

    #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

    Perhatikan bahwa meskipun solusi ini memungkinkan Anda untuk menyimpan newTitlekarena nama properti dan nama pengambil, memiliki metode yang dipanggil -newTitleyang tidak mengembalikan objek yang dimiliki oleh penelepon dapat membingungkan bagi orang lain yang membaca kode Anda.


Sebagai catatan, Apple telah menerbitkan Transitioning to ARC Release Notes , di mana mereka menyatakan:

Anda tidak dapat memberikan properti nama yang dimulai dengan newatau copy.

Mereka sudah diberitahu bahwa pernyataan mereka tidak cukup akurat: pelakunya adalah nama metode pengambil, bukan nama properti.


Sunting 17 Jan 2015: Saya baru saja melihat komit terbaru untuk Dentang yang menyarankan opsi 3 di atas (menggunakan objc_method_family(none)), untuk memperbaikinya, untuk kasus umum di mana nama properti cocok dengan salah satu awalan keluarga metode khusus. Xcode kemungkinan akan memasukkan perubahan ini pada akhirnya.

Cur
sumber
6
Bekerja seperti pria yang mempesona !! Terima kasih!!! Untuk referensi di masa mendatang - saya menggunakan "@property (kuat, nonatomik, pengambil = theNewTitle) NSString * newTitle;"
Noam
8
Jawaban yang bagus Saya memiliki variabel yang diawali "baru."
Saya punya masalah ini juga, dan itu membuang banyak waktu saya! Anda benar-benar jenius ~ Terima kasih!
H Lai
NS_RETURNS_NOT_RETAINEDapa yang Anda butuhkan juga.
DawnSong
55

Nama Objek Tidak Dapat Diterima

  • tombol baru
  • copyLabel
  • mengalokasikan Judul

Nama Objek yang Dapat Diterima

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc # disintesis secara otomatis # xcode-4.6.1

** EDIT **

Tampaknya Anda juga tidak dapat menggunakan mutableCopy .

Jacksonkr
sumber
1
Saya juga memperhatikan bahwa "copy" tidak dapat digunakan sampai sekarang.
Rishab
30

Nama anggota yang dimulai dengan yang baru itulah yang memicu peringatan. Ubah nama menjadi editedTitle dan peringatan akan hilang. Saya tidak dapat menemukan dokumentasi yang mengonfirmasi hal ini, tetapi melalui pengujian dapat menentukan bahwa variabel anggota yang dimulai dengan 'baru' memperburuk kompiler.

Michael
sumber
8

ARC tidak mengizinkan untuk menggunakan "Baru ...." dalam nama properti. tetapi Anda dapat menggunakan "newTitle" dengan mengubah nama pengambil.

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

Sepertinya Bavarious tidak menyarankan apa yang ingin Anda lakukan. Yang ingin Anda lakukan adalah mendeklarasikan variabel instan NewTitledan kemudian mensintesis properti. Kami dulu harus mendeklarasikan variabel instance dan properti. Tidak lagi.

Sekarang, saya percaya cara yang tepat untuk melakukan ini adalah sebagai berikut:

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

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

Variabel instance untuk properti newTitledisintesis. Anda tidak ingin variabel instan Anda sama dengan properti Anda - terlalu mudah untuk membuat kesalahan .

Lihat Contoh: Mendeklarasikan Properti dan Mensintesis Accessors

aquraishi
sumber
Itu tergantung pada versi kompiler. Versi terbaru dentang memancarkan peringatan dalam kasus ini, itulah sebabnya saya telah menyebutkan versi kompiler dalam jawaban saya.
Saya tidak berpikir Anda memecahkan masalah. Untuk Xcode 9, ini merupakan kesalahan, bukan peringatan. NS_RETURNS_NOT_RETAINEDadalah apa yang kamu butuhkan.
DawnSong
4

Di CoreData jika Anda menggunakan atribut "new ..." (kompilasi secara normal) itu akan crash secara acak dengan pengecualian "akses buruk".

Tidak ada log mogok dan garis yang ditampilkan dengan "Semua Pengecualian Breakpoint" tidak akan membantu Anda sama sekali.

las
sumber
3

Menulis setter secara manual dengan nama yang sama dengan properti menghapus peringatan ini.

Serge Rykovski
sumber
Dalam Xcode 7.3, ini tidak membantu. Kesalahan masih muncul di baris definisi properti.
arlomedia
1

Selain masalah bahwa Anda harus / tidak dapat menggunakan "baru" di depan Anda nama properti, katakan satu hal lagi: Cobalah untuk menghindari "baru" di depan nama secara umum. "Baru" tergantung pada waktu. Saat ini baru untuk Anda, tetapi beberapa waktu kemudian Anda mungkin ingin menerapkan sesuatu yang baru lagi. Jadi menggunakan "baru" dalam nama selalu buruk. Cobalah untuk berpikir seperti ini: Di ​​dunia pemrograman, "baru" selalu menciptakan sesuatu: contoh baru dari sesuatu.

Dalam kasus Anda ketika Anda ingin menetapkan judul yang berbeda maka beri nama properti Anda saat ini titleReplacement.

Satu hal lagi: Cobalah untuk menyebutkan fungsi dan metode dengan kata kerja terlebih dahulu, seperti setSomething atau getSomething. Tetapi pada properti coba beri nama objek terlebih dahulu, seperti heightMinimum, heightMaximum, dll. -> saat Anda menggunakan inspektur saat Anda membuat kode, Anda selalu mencari objek. Cobalah. ;-)

Philipp Schaller
sumber
1

NS_RETURNS_NOT_RETAINED digunakan untuk memecahkan masalah penamaan.

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

Kita dapat menemukan definisinya sebagai berikut,

#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

Atribut 'ns_returns_not_retained' adalah pelengkap dari 'ns_returns_retained'. Di mana fungsi atau metode dapat muncul untuk mematuhi konvensi Kakao dan mengembalikan objek Kakao yang ditahan, atribut ini dapat digunakan untuk menunjukkan bahwa referensi objek yang dikembalikan tidak boleh dianggap sebagai referensi "memiliki" dikembalikan ke penelepon. Kerangka kerja Foundation mendefinisikan NS_RETURNS_NOT_RETAINED makro yang secara fungsional setara dengan yang ditunjukkan di bawah ini.

Lampirkan detail lebih lanjut di sini.

DawnSong
sumber
-2

coba ini:-

@property (nonatomic,retain) NSString *newTitle;
Gypsa
sumber
1
Namun, masalah persis sama. FYI, garis kesalahan ada di jalur @sintesis.
Noam