iOS 每天一道面試題

同為菜逼,共同努力。

1.nil Nil NULL NSNull 區別。

nil:指向oc中對象的空指針,針對對象。

Nil:指向oc中類的空指針,針對類。

NULL:指向其他類型的空指針,如一個c類型的內存指針,基本數據類型為空,基本類型。

NSNull:在集合對象中,表示空值的對象。

參考博客這是我發現寫的比較詳細的博客.

2.你是否接觸過oc中的反射機制?簡單聊一下概念和使用.

    //    ? class反射
    //    ? 通過類名的字符串形式實例化對象
    Class class1 = NSClassFromString(@"UILabel");
    id label = [[class1 alloc ]init];
    NSLog(@"label = %@",label);
    //    ? 將類名變為字符串
    Class class2 =[UILabel class];
    NSString *className = NSStringFromClass(class2);
    NSLog(@"className = %@",className);

    Student *stu = [[Student alloc] init];
    //    ? SEL的反射
    //    ? 通過方法的字符串形式實例化方法
    SEL selector = NSSelectorFromString(@"setName:");
    [stu performSelector:selector withObject:@"GanMaoShen"]; //注意如果有兩個參數,使用兩個withObject:參數;
    NSLog(@"stu.name =%@",stu.name);
    //    ? 將方法變成字符串
    NSString *select =  NSStringFromSelector(@selector(testVoidFuncWithTestParam:));
    NSString *select2 =  NSStringFromSelector(_cmd);
    NSLog(@"select =%@ select2 = %@",select,select2);
2017-03-27 20:19:07.658 test[10559:3059755] label = <UILabel: 0x7fdcae00fed0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6000002834d0>>
2017-03-27 20:19:07.659 test[10559:3059755] className = UILabel
2017-03-27 20:19:07.659 test[10559:3059755] stu.name =GanMaoShen
2017-03-27 20:19:07.659 test[10559:3059755] select =testVoidFuncWithTestParam: select2 = viewDidLoad

3.Block的傳值,傳址,內存管理,循環引用(retain cycle)。(狠補了一下block的知識,發現block中很多知識點,所以還是要弄透)

兩篇很好的block基礎博客
block的用法,定義.
block兩個界面的傳值.

void test1()
{
  int a = 10;
}
void test2()
{
    __block int a = 10;
}
void test3()
{
    static int a = 10;
}
int a = 10;
void test4()
{
}
總結:block中只有普通局部變量(test1)是傳值,其他情況(test2,test3,test4)都是傳址。
#block的內存管理
ARC下:
- block可以使用copy和strong,并且是一個對象。

#Block如果沒有引用外部變量
保存在全局區(MRC/ARC一樣)
#Block如果引用外部變量
ARC保存在 堆區; MRC保存在 棧區必須用copy修飾block;

推薦博客深入淺出-iOS Block原理和內存中位置

block循環引用
1.如果block代碼塊的內部,使用了外面的強引用對象,block代碼塊的內部會自動產生一個強引用,引用著該對象,不會銷毀,造成循環引用.
解決:下面代碼在block外部實現.
__weak typeof(self) weakSelf = self; 
#define WeakSelf(type)  __weak typeof(type) weak##type = type;
2.但是如果在block內部使用延時操作的還使用弱指針的話會取不到該弱指針,需要在block內部再將弱指針強引用一下.
__strong typeof(self) strongSelf = weakSelf;
#define StrongSelf(type)  __strong typeof(type) strong##type = weak##type;

關于循環引用很好的博客Swift與OC真正去理解Block解決循環引用的技巧

4.如何在@category和@protocol中添加@property

首先你要知道category和protocol和作用和區別,同時回顧這道題的同時,同時回顧extension 和category。
extension看起來很像一個匿名的category,但是extension和有名字的category幾乎完全是兩個東西。 extension在編譯期決議,它就是類的一部分,在編譯期和頭文件里的@interface以及實現文件里的@implement一起形成一個完整的類,它伴隨類的產生而產生,亦隨之一起消亡。extension一般用來隱藏類的私有信息,你必須有一個類的源碼才能為一個類添加extension,所以你無法為系統的類比如NSString添加extension。
更深入一點的話我推薦這個帖子。iOS 類別不能添加屬性原理?

@dynamic 和 @synthesize的區別:
在@implementation 中通過@dynamic xxx 告訴編譯器、xxx屬性的setter、getter方法由開發者自己來生成
@ synthesize xxx = _xxx; 告訴編譯器、xxx屬性的setter、getter方法由編譯器來生成、同時用_xxx 來合成 成員變量

好,步入正題。

4.1@protocol中添加property

在protocol中添加property時,其實就是聲明了 getter 和 setter 方法,在實現這個protocol協議的類中,我們要自己手動添加實例變量,并且需要實現setter/getter方法,實現setter/getter方法有兩種方式,一種是自動生成(@synthesize) ,另一種是手動生成(@dynamic)此時又有了拓展問題(@synthesize和@dynamic的作用 見 題5)

@protocol PersonDelegate <NSObject>
@property (nonatomic, copy) NSString *name;
@end
//personn類
@interface Person : NSObject
@end
#import "Person.h"
@interface Student : NSObject <PersonDelegate>
- (void)testLog;
@end
#import "Student.h"

@implementation Student
//自動實現setter和getter方法
@synthesize name;

- (void)testLog {
    NSLog(@"self.name=%@",self.name);
}

@end

手動實現setter和getter

#import "Person.h"
@interface Student2 : NSObject <PersonDelegate>
{
    //聲明一個實例變量
    NSString *_name;
}
- (void)testLog;
@end

#import "Student2.h"

@implementation Student2
@dynamic name;
- (void)testLog {
    NSLog(@"self.name=%@",self.name);
}
- (void)setName:(NSString *)name
{
    _name = name;
}
- (NSString *)name
{
    return _name;
}
@end
    Student *stu1 = [Student new];
    stu1.name = @"testName";
    [stu1 testLog];
    Student2 *stu2 = [Student2 new];
    stu2.name = @"testName";
    [stu2 testLog];

關于category實現property主要是利用runtime的關聯方法(mjrefresh中也有用到)。

objc_setAssociatedObject   objc_getAssociatedObject
@interface Person (Test)
@property (nonatomic, copy) NSString *tmpName;
- (void)testLog;
@end
#import "Person+Test.h"
#import <objc/runtime.h>

@implementation Person (Test)
- (void)setTmpName:(NSString *)tmpName
{
    objc_setAssociatedObject(self, @selector(tmpName), tmpName, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)tmpName
{
    return objc_getAssociatedObject(self, @selector(tmpName));
}
- (void)testLog {
    NSLog(@"self.name=%@",self.tmpName);
}
@end
    Person *p1 = [Person new];
    p1.tmpName = @"tmpName";
    [p1 testLog];

當然還有一種利用臨時變量的方法完成添加屬性的方法。參考博客
iOS Category 和 Protocol 中的 Property 你們真的會了么?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 2,013評論 0 7
  • 多線程、特別是NSOperation 和 GCD 的內部原理。運行時機制的原理和運用場景。SDWebImage的原...
    LZM輪回閱讀 2,035評論 0 12
  • 面試筆試都是必考語法知識的。請認真復習和深入研究OC。 Objective-C 方法和選擇器有何不同?(Diffe...
    b485c88ab697閱讀 5,730評論 0 35
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,426評論 0 35
  • 1,NSObject中description屬性的意義,它可以重寫嗎?答案:每當 NSLog(@"")函數中出現 ...
    eightzg閱讀 4,190評論 2 19