更新記錄
時間 | 版本修改 |
---|---|
2020年4月3日 | 初版 |
2020年4月17日 | 詳細描述了實現"協議中的屬性"的問題 |
新建iOS工程去掉storyBoard
- 去掉storyBoard的3個步驟,參考iOS 開發之刪除 storyboard
- 遇到不能識別selector的錯誤,-[AppDelegate setWindow:]: unrecognized selector sent to instance
- 參考iOS13生命周期的改動,需要給AppDelegate類添加一個屬性:
@property (strong, nonatomic) UIWindow * window;
- 去掉storyBoard之后黑屏的問題,參考關於xcode11新建項目的黑屏那點事
一個小插曲
- 給
AppDelegate
添加window
屬性時,直接添加了匿名分類中,報錯:Illegal redeclaration of property in class extension 'AppDelegate' (attribute must be 'readwrite', while its primary must be 'readonly')
- 參考Xcode中出現Illegal redeclaration of property in class extension,該屬性重復聲明了。
- 但是為什么可以放置在.h文件,而不能放置在匿名分類里面呢?
- 參考能否向Protocol中添加屬性?
- 結論
- 協議中的屬性,聲明了setter方法和getter方法。
- 匿名分類中添加屬性,但是不會自動生成setter方法和getter方法。
上述問題總結
- 協議中的屬性(即property)其實只聲明了setter方法和getter方法,並沒有實例變量。(想一下通用編程模式中接口的概念,是指某個類型實現了某些接口,而接口本身是不含有數據的。【注:這里的接口實質上就是iOS中所說的“協議”】)
- 協議中的方法都是對外公開的
- 匿名分類(即類擴展)中的屬性,都是不對外公開(即private的)。
- 所以將協議中的屬性,在匿名分類中實現,是一件非常奇怪的事情。因為協議本身聲明了這個屬性是public的,而匿名分類中又聲明該屬性是private的。所以編譯器會報錯,不知道該怎么處理。
- 如果想躲過編譯器的報錯,可以在頭文件中聲明該屬性為readonly, 在匿名分類中聲明該屬性為readwrite。
- 但是在子類中修改協議(或者基類)的屬性的對外權限時,是有警告的:
Attribute 'readonly' of property 'window' restricts attribute 'readwrite' of property inherited from 'UIApplicationDelegate'
- 但是在子類中修改協議(或者基類)的屬性的對外權限時,是有警告的:
- 或者在頭文件中直接聲明該屬性(就相當於繼承了協議的setter方法和getter方法),並且也聲明了一個實例變量。
- 與上述同等的做法,就是加入
@synthesize
聲明。
如果根視圖沒有鋪滿全屏
寫在后面的話
- 我第二次新建XCode demo的時候,仍然遇到了很多個問題,幸好之前都在此記錄下了之前遇到的問題及解決方法。
- 如果有讀者的demo無法正常運行的話,建議參考上述提及的每一個參考鏈接,都照着做一遍,就可以進入Hello World了!