0

我收到以下错误:

在此处输入图像描述

我看不出我的代码有什么问题。这是我的 AHInstagramImageData 中的一些代码

-(id)initWithData:(NSDictionary *)data
{
    self = [super init];
    if (!self) {
        return nil;
    }

for (NSDictionary * comment in imgCmt){
        AHInstagramImageComment * instagramImgComment  = [[AHInstagramImageComment alloc] initWithData:comment];
        [comments insertObject:instagramImgComment atIndex:0];
        [instagramImgComment release];
    }
}

and then on the AHInstagramImageComment I have:

-(id)initWithData:(NSDictionary *)data
{
    self = [super init];
    if (!self) {
        return nil;
    }

    [self calculateCommentsHeight];

    return self;
}

- (void) calculateCommentsHeight
{
    NSString *combinedComment = [NSString stringWithFormat:@"%@ %@", self.username, self.text];
    CGFloat desiredHeight = [combinedComment sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:14] constrainedToSize:CGSizeMake(kCommentsMaxWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeClip].height;

    if (desiredHeight >= 50){
        commentHeight_ = desiredHeight;
    } else {
        commentHeight_ = 50;
    }

    commentHeight_ += kTimestampMaxHeight;
    commentHeight_ += 5;
}

因此,我必须在后台队列中初始化 AHInstagramImageData:

 [weakSelf.backgroundQueue_ addOperationWithBlock:^{
                             NSArray *arr = [response valueForKey:@"data"];
                             int startingIndex = [[AHImageDataSource sharedDataSource] count];
                             for (NSDictionary * data in arr){
                                 AHInstagramImageData * imgData = [[AHInstagramImageData alloc] initWithData:data];

} }];

这些有错吗?

4

3 回答 3

4

Core Text 在某种程度上是线程安全的,如下所述:Alternative for sizeWithFont: method

使用 CoreText,我编写了一个 NSString 类别,它包装了 CTFramesetterSuggestFrameSizeWithConstraints并且是线程安全的。可能对找到这篇文章并想要不同解决方案的人有用。这与 iOS 5 和 iOS 6 兼容,但出于某种原因在 iOS 6 上提供了更好的结果。

它会为您返回一个建议的 CGSize,但还会告诉您它能够以何种字体大小容纳多少个字符,并接受一个约束。

NSString+SizeCalculation.h

@interface NSString (SizeCalculation)

// Uses CoreText instead of UIStringDrawing, since UIStringDrawing is not thread safe
- (CGSize) sizeWithFontName:(NSString*)fontName constraints:(CGSize)constraint targetSize:(CGFloat)target minimumSize:(CGFloat)minimum optimalFontSize:(CGFloat*)optimal fitRange:(NSRange*)range;

@end

NSString+SizeCalculation.m

#import <CoreText/CoreText.h>
@implementation NSString (SizeCalculation)

- (CGSize) sizeWithFontName:(NSString*)fontName constraints:(CGSize)constraint targetSize:(CGFloat)target minimumSize:(CGFloat)minimum optimalFontSize:(CGFloat*)optimal fitRange:(NSRange*)range
{
    CFRange fitRange;
    CGSize suggestion;
    do {
        id font = (__bridge_transfer id) CTFontCreateWithName((__bridge CFStringRef) fontName, target, NULL);
        NSAttributedString *string = [[NSAttributedString alloc] initWithString:self attributes:@{(id)kCTFontAttributeName:font}];
        id framesetter = (__bridge_transfer id) CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) string);
        suggestion = CTFramesetterSuggestFrameSizeWithConstraints((__bridge CTFramesetterRef)(framesetter), CFRangeMake(0, self.length), nil, constraint, &fitRange);
    } while (fitRange.length < self.length && target > minimum && (target -= 2.0f));

    if (optimal != NULL) *optimal = target;
    if (range != NULL) *range = NSMakeRange(fitRange.location,fitRange.length);
    return suggestion;
}

@end

你像这样使用它。

 CGFloat fontSize = 24.0f;
 NSRange range;
 NSString *title = @"Hello World";
 CGSize suggestedSize = [title sizeWithFontName:@"HelveticaNeue-Bold" constraints:CGSizeMake(200.0f,35.0f) targetSize:fontSize minimumSize:16.0f optimalFontSize:&fontSize fitRange:&range];

SuggestedSize 然后包含一个CGSize,它将适合字体fontSize的标题。范围还告诉您在达到最小尺寸之前它能够容纳多少个字符。如果您不在乎,可以将 NULL 传递给最佳尺寸和适合范围。

Ps 我尝试重新使用 CoreText 部分,但它没有工作,因此需要重新初始化,但它仍然非常快,并且由于您在后台线程上运行它会很好。

Pps 如果你只需要获取单行文本的高度,我写了一个性能更好的类似方法。https://gist.github.com/duedal/4742069

于 2013-01-24T19:18:37.973 回答
3

我之前遇到过类似的问题。当前有一个错误阻止[NSString sizeWithFont:][NSString drawInRect:]在后台线程上运行,或者通过NSOperations.

请参阅此链接: UIKit 字符串绘制方法中的错误?

你有几个选择:

  1. 不要sizeWithFont:NSOperations.
  2. 将您的最大操作计数设置NSOperationQueue为 1:

    [queue setMaxConcurrentOperations:1];

  3. 使用 Core Text 和NSAttributedStrings,它们有自己的 " sizeWithFont" 方法:CTFramesetterSuggestFrameSizeWithConstraints

  4. 用于[NSOperationQueue mainQueue];在主线程上运行操作。
于 2012-09-20T04:00:24.133 回答
0

WebCore/WebKit 不是完全线程安全的,必须在主线程上运行。问题是,字体和字符串操作在幕后使用了 WebKit。

在主线程上调用您的字符串绘图(包括调整大小)代码,崩溃应该停止。

于 2012-09-20T04:04:50.710 回答