简体   繁体   English

电弧在 Objective-C

[英]ARC in Objective-C

Hi, guys!嗨,大家好! Currently I'm reading a book "Programming in Objective-C" by Stephen Kochan.目前我正在阅读 Stephen Kochan 的一本书“Programming in Objective-C” Actually I'm already finished reading it.其实我已经看完了。 But now I returned to the Chapter #13 - "Underlying C Language Features".但现在我回到了第 13 章——“底层 C 语言特性”。 After reading the Chapter, I did all exercises, but I stuck on one of them.读完这一章后,我做了所有的练习,但我坚持了其中一个。 The problem is that now I'm using ARC in my projects, and the code that I wrote gives me an error.问题是现在我在我的项目中使用 ARC,而我编写的代码给我一个错误。 When I fix it I got incorrect output. So here is the code of my Fraction Class and Main .当我修复它时,我得到了不正确的 output。所以这是我的Fraction ClassMain的代码。

Fraction.h分数.h

#import <Foundation/Foundation.h>

@interface Fraction : NSObject {
    int numerator;
    int denominator;
}

@property int numerator, denominator;

-(void) print:(BOOL)reduceCheck;
-(void) setNumerator:(int)numerator andDenominator:(int)denominator;
-(double) convertToNum;
-(Fraction *) add:(Fraction *)fraction;
-(Fraction *) subtract:(Fraction *)fraction;
-(Fraction *) multiply:(Fraction *)fraction;
-(Fraction *) divide:(Fraction *)fraction;
-(void) reduce;
-(id)initWithNumerator:(int)numeratorValue andDenominator:(int)denominatorValue;
-(void)printOut;
-(id)init;
+(Fraction *)allocFraction;
+(int)objectCounter;
+(int)methodAddInvokedCounter;

@end

Fraction.m分数.m

#import "Fraction.h"

static int gObjectCounter;

static int gMethodInvokedCounter;

static int greatestCommonDivisor(int u, int v) {
    int temp;

    while(v != 0) {
        temp = u % v;
        u = v;
        v = temp;
    }
    return u;
}

@implementation Fraction

@synthesize numerator, denominator;

-(void) print:(BOOL)reduceCheck {
    Fraction *resultFraction = [[Fraction alloc] init];
    [resultFraction setNumerator:numerator andDenominator:denominator];
    if(reduceCheck) {
        [resultFraction reduce];
        NSLog(@"The Fraction is %i/%i - It was reduced", resultFraction.numerator, resultFraction.denominator); 
    }
    else 
        NSLog(@"The Fraction is %i/%i - It was not reduced", resultFraction.numerator, resultFraction.denominator); 

    if(resultFraction.denominator != 1) {
        if(resultFraction.numerator > resultFraction.denominator) {
            Fraction *FractionObject = [[Fraction alloc] init];
            [FractionObject setNumerator:(resultFraction.numerator % resultFraction.denominator) andDenominator: resultFraction.denominator];
            int FractionNumber = resultFraction.numerator / resultFraction.denominator;
            NSLog(@"The Fraction is %i/%i. The whole number of fraction is %i", FractionObject.numerator, FractionObject.denominator, FractionNumber);
        }
        else 
            NSLog(@"The Fraction is %i/%i", resultFraction.numerator, resultFraction.denominator);
    }
    else
        NSLog(@"The whole number of the Fraction is %i", resultFraction.numerator);
}

-(void) setNumerator:(int)value andDenominator:(int)value2 {
    numerator = value;
    denominator = value2;
}

-(double) convertToNum {
    if(denominator != 0)
        return (double)numerator / denominator;
    else
        return NAN;
}

-(Fraction *) add:(Fraction *)fraction {
    //extern int gMethodInvokedCounter;
    Fraction *FractionResult = [[Fraction alloc] init];
    FractionResult.numerator = numerator * fraction.denominator + denominator * fraction.numerator;
    FractionResult.denominator = denominator * fraction.denominator;
    [FractionResult reduce];
    gMethodInvokedCounter++;
    return FractionResult;
}

-(Fraction *) subtract:(Fraction *)fraction {
    Fraction *FractionResult = [[Fraction alloc] init];
    FractionResult.numerator = numerator * fraction.denominator - denominator * fraction.numerator;
    FractionResult.denominator = denominator * fraction.denominator;
    [FractionResult reduce];
    return FractionResult;
}

-(Fraction *) multiply:(Fraction *)fraction {
    Fraction *FractionResult = [[Fraction alloc] init];
    FractionResult.numerator = numerator * fraction.numerator;
    FractionResult.denominator = denominator * fraction.denominator;
    [FractionResult reduce];
    return FractionResult;
}

-(Fraction *) divide:(Fraction *)fraction {
    Fraction *FractionResult = [[Fraction alloc] init];
    FractionResult.numerator = numerator * fraction.denominator;
    FractionResult.denominator = denominator * fraction.numerator;
    [FractionResult reduce];
    return FractionResult;
}

-(void) reduce {
    int u = numerator;
    int v = denominator;

    int greatestCommonDivisor(int u, int v);

    greatestCommonDivisor(u, v);

    numerator /= u;
    denominator /= u;
}

-(id)initWithNumerator:(int)numeratorValue andDenominator:(int)denominatorValue {
    self = [super init];

    if(self) 
        [self setNumerator:numeratorValue andDenominator:denominatorValue];

    return self;
}

-(void)printOut {
    printf("%i/%i", numerator, denominator);
}

-(id)init {
    return [self initWithNumerator:0 andDenominator:0];
}

+(Fraction *)allocFraction {
    //extern int gObjectCounter;
    gObjectCounter++;

    return [Fraction alloc];
}

+(int)objectCounter {
    //extern int gObjectCounter;

    return gObjectCounter;
}

+(int)methodAddInvokedCounter {
    return gMethodInvokedCounter;
}

@end

Main.m主程序

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

Fraction *calculateFractions (Fraction  **array, int numberOfElements) {
    Fraction *resultFraction = [[Fraction alloc] initWithNumerator:array[0].numerator andDenominator:array[0].denominator];
    Fraction *holder;

    for(int i = 1; i < numberOfElements; i++) {
        holder = [resultFraction add:array[i]];
        resultFraction = holder;
    }

    return resultFraction;
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        const int numberOfFractions = 5;

        Fraction *fractionArrayElementOne = [[Fraction alloc] initWithNumerator:5 andDenominator:10];
        Fraction *fractionArrayElementTwo = [[Fraction alloc] initWithNumerator:8 andDenominator:13];
        Fraction *fractionArrayElementThree = [[Fraction alloc] initWithNumerator:7 andDenominator:15];
        Fraction *fractionArrayElementFour = [[Fraction alloc] initWithNumerator:9 andDenominator:23];
        Fraction *fractionArrayElementFive = [[Fraction alloc] initWithNumerator:4 andDenominator:17];

        Fraction __autoreleasing *arrayOfFractions[numberOfFractions]= {fractionArrayElementOne, fractionArrayElementTwo, fractionArrayElementThree, fractionArrayElementFour, fractionArrayElementFive};

        printf("Fraction Expression: %i/%i + %i/%i + %i/%i + %i/%i + %i/%i = ", arrayOfFractions[0].numerator, arrayOfFractions[0].denominator, arrayOfFractions[1].numerator, arrayOfFractions[1].denominator, arrayOfFractions[2].numerator, arrayOfFractions[2].denominator, arrayOfFractions[3].numerator, arrayOfFractions[3].denominator, arrayOfFractions[4].numerator, arrayOfFractions[4].denominator);

        Fraction *calculateFractions (Fraction **array, int numberOfElements);

        Fraction *resultOfFractionArrayCalculation; 

        resultOfFractionArrayCalculation = calculateFractions(arrayOfFractions, 5);

        printf("%i/%i\n", resultOfFractionArrayCalculation.numerator, resultOfFractionArrayCalculation.denominator);

    }
    return 0;
}

Output Output
Fraction Expression: 5/10 + 8/13 + 7/15 + 9/23 + 4/17 = 1/0分数表达式:5/10 + 8/13 + 7/15 + 9/23 + 4/17 = 1/0

Question: What I'm doing wrong?问题:我做错了什么?

Thanks in advance!提前致谢!

There's a bug in the reduce method. reduce 方法中存在错误。 You throw away the result of the gcd and just divide the numerator and denominator by the numerator.你扔掉 gcd 的结果,只用分子和分母除以分子。 As soon as numerator > denominator you'll end up with 1/0 as your fraction.一旦numerator > denominator ,你最终会得到 1/0 作为你的分数。

As an aside, init should really set the default denominator to 1, not zero.顺便说一句, init确实应该将默认分母设置为 1,而不是零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM