美文网首页
三、object-c进阶

三、object-c进阶

作者: yezide | 来源:发表于2019-06-21 23:18 被阅读0次

6_1_NSNumberTest.m

#import <Foundation/Foundation.h>

int main(int argc, char const *argv[])
{
    @autoreleasepool
    {
        NSNumber* ns1 = [NSNumber numberWithInt: 3];
        NSLog(@"ns1=%@", ns1);
    }
    return 0;
}

6_4_KFOutput.h

#import <Foundation/Foundation.h>

@protocol KFOutput
- (void) output;
- (void) addData: (NSString*) msg;
@end

6_4_KFPrintable.h

#import <Foundation/Foundation.h>
#import "6_4_KFOutput.h"
#import "6_4_KFProductable.h"

@protocol KFPrintable <KFOutput, KFProductable>
- (NSString*) printColor;
@end

6_4_KFPrinter.h

#import <Foundation/Foundation.h>
#import "6_4_KFprintable.h"

@interface KFPrinter : NSObject<KFPrintable>
@end

6_4_KFPrinter.m

#import "6_4_KFPrinter.h"
#define MAX_CACHE_LINE 10

@implementation KFPrinter
{
    NSString* printData[MAX_CACHE_LINE];  // 使用数据记录所有需要缓存的打印数据
    int dataNum;  //记录当前需要打印的作业数
}
- (void) output
{
    // 只要还有作业,就继续打包
    while(dataNum > 0)
    {
        NSLog(@"打印机使用%@打印: %@", self.printColor, printData[0]);
        dataNum--;
        for(int i = 0; i < dataNum; i++)
        {
            printData[i] = printData[i + 1];
        }
    }
}

- (void) addData: (NSString*) msg
{
    if(dataNum >= MAX_CACHE_LINE)
    {
        NSLog(@"输出队列已满,添加失败");
    }
    else
    {
        printData[dataNum++] = msg;
    }
}

- (NSDate*) getProduceTime
{
    return [[NSDate alloc] init];
}

- (NSString*) printColor
{
    return @"红色";
}
@end

6_4_KFPrinterTest.m

#import <Foundation/Foundation.h>
#import "6_4_KFPrinter.h"

int main(int argc, char const *argv[])
{
    @autoreleasepool
    {
        KFPrinter* printer = [[KFPrinter alloc] init];
        [printer addData: @"testData1"];
        [printer output];

        NSLog(@"time: %@", [printer getProduceTime]);
    }
}

6_4_KFProductable.h

#import <Foundation/Foundation.h>

@protocol KFProductable
- (NSDate*) getProduceTime;
@end

6_6_ClassTest.m

#import <Foundation/Foundation.h>

int main(int argc, char const *argv[])
{
    @autoreleasepool
    {
        Class cls1 = NSClassFromString(@"NSDate");
        NSLog(@"class is %@", cls1);
        // 使用class来创建对象
        id date = [[cls1 alloc] init];
        NSLog(@"now is %@", date);
        // 通过对象来获取class
        Class cls2 = [date class];
        NSLog(@"cls1 == cls2 ? %d", cls1 == cls2);
        NSLog(@"cls1 == NSDate ? %d", cls1 == NSDate.class);
    }
}

6_6_KFCar.h

#import <Foundation/Foundation.h>

@interface KFCar : NSObject
// - (void) move: (NSNumber*) count;
// - (double) addSpeed: (double) factor;
@end

6_6_KFCar.m

#import <objc/message.h>
#import "6_6_KFCar.h"

@implementation KFCar
- (void) move: (NSNumber*) count
{
    int num = [count intValue];
    for(int i = 0; i < num; i++)
    {
        NSLog(@"    %@", [NSString stringWithFormat: @"汽车正在路上走 %d", i]);
    }
}

- (double) addSpeed: (double) factor
{
    // 以下通过动态的方式来调用move方法
    // 方法1: 通过performSelector, SEL采用@selector
    NSLog(@"  在addSpend方法中动态调用自己的move方法, 方法一: ");
    [self performSelector: @selector(move:)
        withObject: [NSNumber numberWithInt: factor]];
    
    //方法2: 通过performSelector, SEL采用 NSSelectorFromString
    NSLog(@"  在addSpend方法中动态调用自己的move方法, 方法二: ");
    [self performSelector: NSSelectorFromString(@"move:")
        withObject: [NSNumber numberWithInt: factor]];

    // 方法3: 通过objc_msgSend, SEL采用@selector
    NSLog(@"  在addSpend方法中动态调用自己的move方法, 方法二: ");
    objc_msgSend(self, @selector(move:), [NSNumber numberWithInt: factor]);


    // 方法4: 通过objc_msgSend, SEL采用 NSSelectorFromString
    NSLog(@"  在addSpend方法中动态调用自己的move方法, 方法四: ");
    objc_msgSend(self, NSSelectorFromString(@"move:"), [NSNumber numberWithInt: factor]);

    return 100 * factor;
}
@end

6_6_KFCarTest.m

#import "6_6_KFcar.h"

int main(int argc, char const *argv[])
{
    @autoreleasepool
    {
        KFCar* car1 = [[KFCar alloc] init];
        // 因为addSpeed是私有法, 所以不能直接调。 以下代码会报错
        // [car addSpeed: 3];

        // 使用反射机制调用
        Class class = NSClassFromString(@"KFCar");
        id car2 = [[class alloc] init];

        NSLog(@"at main 1");
        [car2 performSelector: @selector(addSpeed:)
            withObject: [NSNumber numberWithDouble: 3]];
        NSLog(@"at main 2");
        objc_msgSend(car2, NSSelectorFromString(@"addSpeed:"), 2.0);
        NSLog(@"at main 3");
        // 这是一种比较屌的方法, 用指向函数的指针来动态调用
        // 先定义函数指针变量
        double (*addSp) (id, SEL, double);
        // 获取car.addSpeed方法, 并将该方法赋给函数指针变量
        addSp = (double (*)(id, SEL, double))[car2 methodForSelector: @selector(addSpeed:)];
        // 通过函数指针调用car对象的方法
        addSp(car2, @selector(addSpeed:), 3);
    }
}

6_7_KFItem.h

#import <Foundation/Foundation.h>

@interface KFItem : NSObject
- (void) info;
@end

6_7_KFItem.m

#import "6_7_KFitem.h"

@implementation KFItem
// 重写init方法
- (id) init
{
    if(self == [super init])
    {
        NSLog(@"  KFItem init方法中, 引用计数为: %ld", self.retainCount);
    }
    return self;
}

- (void) dealloc
{
    NSLog(@"  KFItem dealloc方法中: 系统开始销毁KFItem了, 再见!");
    [super dealloc];
}

- (void) info
{
    NSLog(@"KFItem info");
}
@end

6_7_KFItemTest.m

#import "6_7_KFItem.h"

int main(int argc, char const *argv[])
{
    KFItem* item = [[KFItem alloc] init];

    [item retain]; // 2
    NSLog(@"item retainCount=%ld", [item retainCount]);

    [item retain]; // 3
    NSLog(@"item retainCount=%ld", [item retainCount]);

    [item release];  // 2
    NSLog(@"item retainCount=%ld", [item retainCount]);

    [item retain]; // 3
    NSLog(@"item retainCount=%ld", [item retainCount]);

    [item release]; // 2
    NSLog(@"item retainCount=%ld", [item retainCount]);

    [item release]; // 1
    NSLog(@"item retainCount=%ld", [item retainCount]);

    [item info];
    [item release]; // 0 销毁

    // 经下代码是非常危险的, 看以的是假象, 甚至可能导致程序崩溃
    NSLog(@"item retainCount=%ld", [item retainCount]);
    [item info];
}

6_7_KFUser.h

#import <Foundation/Foundation.h>
#import "6_7_KFItem.h"

@interface KFUser : NSObject
{
    KFItem* _item;
}
- (void) setItem: (KFItem*) item;
- (KFItem*) item;
@end

6_7_KFUser.m

#import "6_7_KFUser.h"

@implementation KFUser
- (void) setItem: (KFItem*) item
{
    if(_item != item)
    {
        [item retain];
        _item = item;
    }
}
- (KFItem*) item
{
    return _item;
}

- (void) dealloc
{
    [_item release];
    NSLog(@"系统开始销毁KFUser对象");
    [super dealloc];
}
@end

6_7_KFUserTest.m

#import <Foundation/Foundation.h>
#import "6_7_KFUser.h"

int main(int argc, char const *argv[])
{
    KFItem* item = [[KFItem alloc] init];
    NSLog(@"item创建出来的引用计数为:%ld", item.retainCount);
    KFUser* user = [[KFUser alloc] init];
    [user setItem: item];
    NSLog(@"被KFUser对象持有后的引用计数为: %ld", item.retainCount);
    [item release];
    NSLog(@"在main中将item的引用计数关系1后为: %ld", item.retainCount);
    [user release];
}

F6_3_1_KFCar.h

#import <Foundation/Foundation.h>

@interface KFCar : NSObject
@property (nonatomic, copy) NSString* brand;
@property (nonatomic, copy) NSString* model;
- (void) drive;
@end

F6_3_1_KFCar.m

#import "F6_3_1_KFCar+drive.h"

@implementation KFCar
- (void) drive
{
    NSLog(@"%@汽车正在路上行驶", self);
}

- (void) drive: (NSString*) owner
{
    NSLog(@"%@正在驾驶%@的汽车在路上飞奔", owner, self);
}

- (NSString*) description
{
    return [NSString stringWithFormat: @"brand=%@, model=%@, color=%@", self.brand, self.model, self.color];
}
@end

F6_3_1_KFCar+drive.h

#import "F6_3_1_KFCar.h"

@interface KFCar ()
@property (nonatomic, copy) NSString* color;
- (void) drive: (NSString*) owner;
@end

F6_3_1_KFCarTest.m

#import <Foundation/Foundation.h>
#import "F6_3_1_KFCar+drive.h"

/**
* 扩展的使用
*/
int main(int argc, char const *argv[])
{
    @autoreleasepool
    {
        KFCar* car = [[KFCar alloc] init];
        car.brand = @"宝马";
        car.model = @"X5";
        car.color = @"黑色";
        [car drive];
        [car drive: @"黎京乐"];
    }
}

F6_3_KFItem.h

#import <Foundation/Foundation.h>

@interface KFItem : NSObject
@property (nonatomic, assign) double price;
- (void) info;
@end

F6_3_KFItem.m

#import "F6_3_KFItem.h"

@implementation KFItem
- (void) info
{
    NSLog(@"this is normal method");
}

- (void) calcDiscount: (double) discount
{

    NSLog(@"this is discount method, final price = %.2f", self.price * discount);
}
@end

F6_3_KFItemTest.m

#import <Foundation/Foundation.h>
#import "F6_3_KFItem.h"

/** 
 * 使用类别调用私有方法
*/
@interface KFItem (kf)
- (void) calcDiscount: (double) discount;
@end

int main(int argc, char const *argv[])
{
    @autoreleasepool
    {
        KFItem* item = [[KFItem alloc] init];
        [item info];

        item.price = 100;
        [item calcDiscount: 0.9];
    }
}

相关文章

网友评论

      本文标题:三、object-c进阶

      本文链接:https://www.haomeiwen.com/subject/prppqctx.html