【问题标题】:Iphone: unable to show photos using AlAssetsLibraryIphone:无法使用 AlAssetsLibrary 显示照片
【发布时间】:2011-12-15 10:40:10
【问题描述】:

我目前将 ipa 发送给朋友进行测试。有趣的是,我的一位测试人员能够查看她存储在使用 iPhone 4 运行 IOS 5 的手机上的照片。

另外 2 位测试者:一位有 iPhone 4 (IOS 4.3.3) 和 iPhone 3GS (IOS 5.0.1),他们都看不到手机上存储的照片。

这些是我使用的代码:

ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
    if(result != NULL) {
        //NSLog(@"See Asset: %@", @"ggg");
        [assets addObject:result];

    }
};

NSLog(@"location = %i      length = %i ", range->location, range->length );

void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) =  ^(ALAssetsGroup *group, BOOL *stop) {
    if(group != nil) {

        NSRange  *datarange = malloc(sizeof(NSRange));

        range->total = [group numberOfAssets];
        datarange->location = [group numberOfAssets] - range->location - range->length;
        datarange->length = range->length;
        NSLog(@" total = %i", range->total);

        int location = [group numberOfAssets] - range->location - range->length;

        if (location < 0)
        {
            datarange->location = 0;
            datarange->length = [group numberOfAssets] - range->location;
        }

        NSIndexSet *indexset = [ [NSIndexSet alloc] initWithIndexesInRange:*datarange];

        [group enumerateAssetsAtIndexes:indexset options:NULL
                             usingBlock:assetEnumerator];

        [indexset release];
        free(datarange);

        [self loadAssetToScrollView:assets]; 

    }

};    

    [assets release];

    assets = [[NSMutableArray alloc] init];


    [library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
                           usingBlock:assetGroupEnumerator
                         failureBlock: ^(NSError *error) {
                             NSLog(@"Failure");
                         }];

    [library release];

我在其他一些线程中看到有人说异步的事情,但不知道是不是这样。他说将 dispatch_async 放在 enumerate group 块中。

有谁知道怎么回事。

另外,iOS 4.3.3 的测试者之一可以在通用->设置下启用定位服务后显示他的照片。为什么我们必须启用它?我们可以在代码上启用它吗,因为它会给使用我们应用程序的用户带来很大的困扰。

【问题讨论】:

    标签: iphone asynchronous photos alassetslibrary


    【解决方案1】:

    同样在 iOS 5.x 上,您必须保留您的 ALAssetsLibrary 实例,只要您需要使用收集的资产。当您在调用[library enumerateGroupsWithTypes:…] 之后像在代码中一样释放ALAssetsLibrary 实例时,所有收集的资产都将无效。

    另请参阅ALAssetsLibrary 文档 - 概述:

    "...从库实例返回的对象的生命周期与库实例的生命周期相关联。..."

    【讨论】:

    • 抱歉回复晚了,我不太明白。你的意思是如果我试图存储 AlAssets 以供以后使用,这些 AlAssets 将是 null 或类似的东西。在我的代码中,我只对 ALAssets 对象的 url 感兴趣,所以我只保留 url 而不是对象本身。所以我还需要关心对象的生命周期吗?
    • 这些收集的资产实例将获得 nil 值(或类似的值),是的。如果您只对资产的 url 感兴趣,那么只收集这些 url。您稍后将在 [assetForURL:resultBlock:failureBlock:] 方法中使用它们来再次检索资产对象。整个事情看起来像 Core Data with Managed Object Context (MOC) 和 ALAssetsLibrary 实例看起来像这个 MOC 实例。因此,在 Core Data 中,当您“关闭”此 MOC 实例时,您无法访问其背后的数据。
    【解决方案2】:

    是的,这非常令人沮丧,但事实就是如此,而且您无法在代码中启用定位服务(虽然这是一件好事)。

    【讨论】:

      【解决方案3】:

      我会将第一个块^assetGroupEnumerator 移动到堆中[[&lt;#block#&gt; copy] autorelease]。为什么?因为这个block会被runloop自动释放,如果有很多assets需要枚举的话。

      【讨论】:

        【解决方案4】:

        还有一件事:不要使用 [self loadAssetToScrollView:assets];在块内,但在块之前获得 self 的弱引用,如下所示:

        __block YourExampleClassInstance *weakSelf = self;
        

        并在块内进一步使用这个weakSelf实例:

        [weakSelf loadAssetToScrollView:assets];
        void (^assetGroupEnumerator)… = ^(ALAssetsGroup *group, BOOL *stop) {
        …
        };
        

        为什么?避免保留循环。

        【讨论】:

        • 你的意思是__weak(或iOS 4 上的__unsafe_unretained)而不是__block
        • 你能给我一个理由吗?抱歉,我对 Objective-c 还是很陌生,我还有很多东西要学。 :(
        • @MarkAdams 嗨,马克,目前我还没有使用 ARC。但是对于 ARCed 项目,您是绝对正确的。
        • @Simon 嗨,Simon,我建议您观看 Apple 的 WWDC2011 Session 308,尤其是在 38:20 的时间点“Block_copy() 不做什么?”滑动。关于保留周期的问题将得到很好的解释。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多